home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.001 / GOLDLIST.PAS < prev    next >
Pascal/Delphi Source File  |  1995-07-12  |  92KB  |  3,120 lines

  1. {--------------------------------------------------------------------------}
  2. {                Product: TechnoJock's Turbo Toolkit                       }
  3. {                Version: GOLD                                             }
  4. {                Build:   1.01                                             }
  5. {                                                                          }
  6. {                Copyright 1986-1995  TechnoJock Software, Inc.            }
  7. {                           All Rights Reserved                            }
  8. {                          Restricted by License                           }
  9. {--------------------------------------------------------------------------}
  10.  
  11.                          {************************}
  12.                          {**  Unit:   GOLDLIST  **}
  13.                          {************************}
  14.  
  15. {++++++++++++++++++++++++++++++} unit GOLDLIST; {++++++++++++++++++++++++++++}
  16.  
  17. {$I GOLDFLAG.INC}
  18. {$IFNDEF GOLDLIST}
  19.    {$DEFINE GOLDLIST}
  20. {$ENDIF}
  21.  
  22. {++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
  23.  
  24. uses DOS, CRT, GoldTint, GoldHard, GoldFast, GoldWin, GoldKey,
  25.      GoldIO, GoldLink, GoldStr, GoldMisc;
  26.  
  27. const
  28.    FirstListCol = ListHi1;
  29.    LastListCol  = ListIcons;
  30.  
  31.    ListMaxHeaders = 4;    {change as necessary}
  32.    ListMaxFooters = 4;    {change as necessary}
  33.  
  34. type
  35.    ListCfgPtr = ^ListCfg;
  36.  
  37.    ListGetStrFunc = function(P:pointer; Element,Start,Finish: longint): string;
  38.    ListGetBitFunc = function(P:pointer; Pick:longint;BitPos:byte): boolean;
  39.    ListSetBitFunc = procedure(P:pointer; Pick:longint;BitPos:byte;On:boolean);
  40.    ListHindHook = procedure(ListDetails:ListCfgPtr);
  41.    ListSelectHook = function(ListDetails:ListCfgPtr):gAction;
  42.    ListColorHook = procedure(Pick:longint; Hi:boolean; var Attr:byte);
  43.    ListCloseProc = function(ListDetails:ListCfgPtr; Handle:integer):boolean;
  44.  
  45.    GridTabArray = array [1..255] of integer;
  46.    pGridTabArray = ^GridTabArray;
  47.  
  48.    ListTints   = array[FirstListCol..LastListCol] of byte;
  49.    ListDataSource = (SourceUnknown,SourceArray,SourceStrLL,SourceSLL,SourceDLL,SourceCustom);
  50.  
  51.    ListCfg = record
  52.       DataSource: pointer;
  53.       DataType: ListDataSource;
  54.       WX1,WY1,WX2,WY2,WStyle: shortint;
  55.       LeftGap,RightGap,BotGap,TopGap: byte;
  56.       TotalNodes: longint;
  57.       ActiveNode: longint;
  58.       TopNode: longint;
  59.       AllowTagging: boolean;
  60.       AllowTwoColors: boolean;
  61.       ChangeColorsWithTags: boolean;
  62.       IODispose: boolean;
  63.       InWindow: boolean;
  64.       Browsing: boolean;
  65.       ColWidth: byte;
  66.       RealColWidth: byte;
  67.       LastColWidth: byte;
  68.       ColCount: byte;
  69.       RowCount: byte;
  70.       Col: ListTints;
  71.       GetStr: ListGetStrFunc;
  72.       GetBit: ListGetBitFunc;
  73.       SetBit: ListSetBitFunc;
  74.       CharHook: KeyPressedHook;
  75.       HindHook: ListHindHook;
  76.       SelectHook: ListSelectHook;
  77.       ColorHook: ListColorHook;
  78.       StrLength: byte;  {length of string element when editing an array}
  79.       LastKey: word;
  80.       LastAction: gAction;
  81.       {header/footer related}
  82.       Headers: array[1..ListMaxHeaders] of ^string;
  83.       ScrollHeader: boolean;
  84.       Footers: array[1..ListMaxFooters] of ^string;
  85.       ScrollFooter: boolean;
  86.       {Grid-specific vars}
  87.       StartingCol: integer;
  88.       LastCol: integer;
  89.       ColumnLock: byte;
  90.       RowLock: byte;
  91.       WriteHeadingsHook: ListHindHook;
  92.       TabsArrayPtr: pGridTabArray;
  93.       TabsArrayPos: integer;
  94.       TabsArrayDim: integer;
  95.       {internal}
  96.       X1,Y1,X2,Y2: byte;  {dimensions of list (including headings)}
  97.       {desk - internal}
  98.       DeskListCloseCallBack: ListCloseProc;
  99.    end; { ListCfg }
  100.  
  101.    DeskBrowseFileInfo = record   {attached to a window's UserData}
  102.       Cfg: ListCfg;
  103.       DataList: DoubleLL;
  104.    end; { DeskBrowseFileInfo }
  105.  
  106.    ListSet = record
  107.       LastEcode: integer;
  108.       ListLeft: string[1];
  109.       ListRight: string[1];
  110.       ListTag: string[1];
  111.       GridLeft: string[1];
  112.       GridRight: string[1];
  113.       GridTag: string[1];
  114.       ToggleKey: word;
  115.       TagKey: word;
  116.       UnTagKey: word;
  117.       TagAllKey: word;
  118.       UnTagAllKey: word;
  119.       WinStyle:byte;
  120.       WX1: byte;          {default dimensions of list window}
  121.       WY1: byte;
  122.       WX2: byte;
  123.       WY2: byte;
  124.       WrapWinType: WinType;
  125.       LastActiveItem:longint;
  126.       EMsgFunc: ErrMsgFunc;
  127.    end; {List Set}
  128.  
  129. {Misc}
  130. function  LastListError: integer;
  131. {generic list managment}
  132. procedure InitListCFG(var ListDetails: ListCfg);
  133. {hooks}
  134. procedure ListAssignHindHook(var ListDetails: ListCfg; Proc:ListHindHook);
  135. procedure ListAssignCharHook(var ListDetails: ListCfg; Proc:KeyPressedHook);
  136. procedure ListAssignSelectHook(var ListDetails: ListCfg; Proc:ListSelectHook);
  137. procedure ListAssignColorHook(var ListDetails: ListCfg; Proc:ListColorHook);
  138. procedure ListRemoveHindHook(var ListDetails: ListCfg);
  139. procedure ListRemoveCharHook(var ListDetails: ListCfg);
  140. procedure ListRemoveSelectHook(var ListDetails: ListCfg);
  141. procedure ListRemoveColorHook(var ListDetails: ListCfg);
  142. {heading management}
  143. procedure ListAssignHeader(var ListDetails: ListCfg; Line:byte; var Heading:string);
  144. procedure ListAssignFooter(var ListDetails: ListCfg; Line:byte; var Footnote:string);
  145. procedure ListRemoveHeader(var ListDetails: ListCfg; Line:byte);
  146. procedure ListRemoveFooter(var ListDetails: ListCfg; Line:byte);
  147. procedure ListScrollHeader(var ListDetails: ListCfg; On:boolean);
  148. procedure ListScrollFooter(var ListDetails: ListCfg; On:boolean);
  149. {general configuration}
  150. procedure ListSetTagging(var ListDetails: ListCfg; On:boolean);
  151. procedure ListSetTwoColors(var ListDetails: ListCfg; On:boolean);
  152. procedure ListSetTagColor(var ListDetails: ListCfg; On:boolean);
  153. procedure ListSetWin(var ListDetails: ListCfg; X1,Y1,X2,Y2:integer; Style:byte);
  154. procedure ListSetGaps(var ListDetails: ListCfg; LeftGap,RightGap,BotGap,TopGap: byte);
  155. procedure ListSetColor(var ListDetails: ListCfg; A:TintElement;C:byte);
  156. procedure ListSetColWidth(var ListDetails: ListCfg; Width: byte);
  157. {assigning the information source}
  158. procedure ListAssignArray(var ListDetails: ListCfg; var ListSource; StrLen:Byte;ArrayElements:byte);
  159. procedure ListAssignSLL(var ListDetails: ListCfg; var TheList:SingleLL);
  160. procedure ListAssignDLL(var ListDetails: ListCfg; var TheList:DoubleLL);
  161. procedure ListAssignCustom(var ListDetails: ListCfg; Total:longint; Proc:ListGetStrFunc);
  162.  
  163. {browsing}
  164. procedure RunBrowse(var ListDetails: ListCfg;Tit:StrScreen);
  165. function  LaunchBrowse(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  166. procedure RunBrowseFile(Fname:PathStr;Tit:StrScreen);
  167. function  LaunchBrowseFile(Fname:PathStr;Tit:StrScreen): byte;
  168. {basic list windows}
  169. function  RunListStrLL(ListSource:StringLL;Tit:StrScreen):longint;
  170. {list display}
  171. procedure RunList(var ListDetails: ListCfg;Tit:StrScreen);
  172. function  LaunchList(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  173. procedure ShowList(var StrArray;StrLength:byte;TotalPicks:integer);
  174.  
  175. {Internal}
  176. procedure NoListCharHook(var K : word;var X,Y:byte);
  177. procedure NoListHindHook(ListDetails:ListCfgPtr);
  178. procedure NoListColorHook(Pick:longint;Hi:boolean;  var Attr:byte);
  179. procedure RefreshHeadFoot(var ListDetails: ListCfg);
  180. procedure RecalcListDimensions(var ListDetails: ListCfg);
  181. procedure BrowseRefresh(var ListDetails: ListCfg);
  182. procedure BrowseProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte; MakeLocal: boolean);
  183. procedure GListRefresh(var ListDetails: ListCfg; Status:gStatus);
  184. procedure GListProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  185. procedure WrapListProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  186. procedure WrapListRefresh(var ListDetails: ListCfg; Status:gStatus);
  187. procedure ToggleTagState(var ListDetails: ListCfg);
  188. procedure SetTag(var ListDetails: ListCfg; On: boolean);
  189. procedure SetTagAll(var ListDetails: ListCfg; On: boolean);
  190. procedure DelayIt(L,InWin:boolean;var WaitTime:integer);
  191. procedure SetInnerDimensions(var ListDetails: ListCfg);
  192. function  ListScrollUp(var ListDetails: ListCfg): boolean;
  193. function  ListScrollDown(var ListDetails: ListCfg): boolean;
  194. function  ListScrollPgDn(var ListDetails: ListCfg): boolean;
  195. function  ListScrollPgUp(var ListDetails: ListCfg): boolean;
  196. function  ListScrollHome(var ListDetails: ListCfg): boolean;
  197. function  ListScrollEnd(var ListDetails: ListCfg): boolean;
  198. function  ListCloseHandler(Handle: integer):boolean;
  199. procedure ListFocusHandler(Handle: integer);
  200.  
  201. {$IFDEF TTT5}
  202. Procedure Default_Settings;
  203. Procedure Show_List(var StrArray;StrLength:Byte;TotalPicks:byte);
  204. Procedure New_Show_List(var StrArray;StrLength:Byte;TotalPicks:byte);
  205. {$ENDIF}
  206.  
  207. var
  208.    ListVars: ListSet;
  209.    LPicks: integer;
  210.  
  211. {+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
  212.  
  213. {$IFOPT F-}
  214.    {$DEFINE FOFF}
  215.    {$F+}
  216. {$ENDIF}
  217. function ListEMsg(ECode:integer): string;
  218. {}
  219. begin
  220.    case Ecode of
  221.       0: exit;
  222.       1001 : ListEMsg := 'Unable to load file for browsing';
  223.       1002 : ListEMsg := 'Not enough memory to load entire file';
  224.       1003 : ListEMsg := 'Header/Footer out of range';
  225.       1004 : ListEMsg := 'Unable to create the browse/list window';
  226.       else
  227.          ListEMsg := 'Internal List error';
  228.    end; {case}
  229. end; { ListEMsg }
  230. {$IFDEF FOFF}
  231.    {$F-}
  232.    {$UNDEF FOFF}
  233. {$ENDIF}
  234.  
  235. procedure ListSetError(ECode:integer);
  236. {}
  237. {$IFOPT D+}
  238. var Msg: string;
  239. {$ENDIF}
  240. begin
  241.    ListVars.LastEcode := ECode;
  242. {$IFOPT D+}  {if debug active display an error message and terminate}
  243.    if Ecode <> 0 then
  244.    begin
  245.       str(Ecode,Msg);
  246.       Msg := Msg+': '+ListVars.EMsgFunc(Ecode);
  247.       SetWinIgnore(true);
  248.       if PromptCustom(' GoldList Error ',Msg,' ~I~gnore ',' ~A~bort ','',279,286,0,0, 10000) = 2 then
  249.          Halt;
  250.    end;
  251. {$ENDIF}
  252. end; {ListSetError}
  253.  
  254. function LastListError: integer;
  255. {}
  256. begin
  257.    LastListError := ListVars.LastEcode;
  258. end; { LastListError }
  259.  
  260.                           {*********************}
  261.                           {**  Miscellaneous  **}
  262.                           {*********************}
  263.  
  264. procedure DelayIt(L,InWin:boolean;var WaitTime:integer);
  265. {Used in scrolling routines such as list, ScrollField and the SpinFields}
  266. begin
  267.    if L then
  268.    begin
  269.      if InWin then
  270.          WinDrawTop;
  271.      delay(WaitTime);
  272.      if WaitTime <> KeyVars.ScrollDelay then
  273.         WaitTime := KeyVars.ScrollDelay;
  274.    end;
  275. end; { DelayIt }
  276.  
  277. procedure CalcColRow(var ListDetails: ListCfg);
  278. {}
  279. begin
  280.    with ListDetails do
  281.    begin
  282.       if (ColWidth = 0) or (ColWidth > X2-X1) then
  283.       begin
  284.          RealColWidth := X2-X1;
  285.          LastColWidth := RealColWidth;
  286.          ColCount := 1;
  287.       end
  288.       else
  289.       begin
  290.          RealColWidth := ColWidth;
  291.          ColCount := (X2-X1) div RealColWidth;
  292.          LastColWidth := (X2-X1) - ColCount * RealColWidth;
  293.          if LastColWidth = 0 then
  294.             LastColWidth := RealColWidth
  295.          else
  296.             inc(ColCount);
  297.       end;
  298.       RowCount := succ(Y2-Y1);
  299.    end;
  300. end; {CalcColRow}
  301.                      {*******************************}
  302.                      {**  Generic List Management  **}
  303.                      {*******************************}
  304. {$IFOPT F-}
  305.    {$DEFINE FOFF}
  306.    {$F+}
  307. {$ENDIF}
  308. function DummyGetStr(P:pointer;Element,Start,Finish: longint): string;
  309. {}
  310. begin
  311.    DummyGetStr := '';
  312. end; { DummyGetStr }
  313.  
  314. function DummyGetBit(P:pointer;Pick:longint;BitPos:byte): boolean;
  315. {}
  316. begin
  317.    DummyGetBit := false
  318. end; { DummyGetBit }
  319.  
  320. procedure DummySetBit(P:pointer;Pick:longint;BitPos:byte;On:boolean);
  321. {}
  322. begin
  323. end; { DummySetBit }
  324.  
  325. function ArrayGetStrFunc(P:pointer;Element,Start,Finish: longint): string;
  326. {}
  327. var
  328.   W : longint;
  329.   TempStr : String;
  330.   ArrayOffset: word;
  331. begin
  332.    with ListCfg(P^) do
  333.    begin
  334.       if (Element < 1) or (Element > TotalNodes) then
  335.          TempStr := ''
  336.       else
  337.       begin
  338.          {move array string to Temp}
  339.          W := pred(Element) * succ(StrLength);
  340.          ArrayOffset := Ofs(DataSource^) + W;
  341.          move(Mem[Seg(DataSource^):ArrayOffset],TempStr,1);
  342.          move(Mem[Seg(DataSource^):succ(ArrayOffset)],TempStr[1],ord(TempStr[0]));
  343.       end;
  344.       if length(TempStr) < succ(Finish - Start) then
  345.          TempStr := PadLeft(TempStr,succ(Finish - Start),' ');
  346.       ArrayGetStrFunc := TempStr;
  347.    end;
  348. end; { ArrayGetStrFunc }
  349.  
  350. function SLLGetStrFunc(P:pointer;Element,Start,Finish: longint): string;
  351. {}
  352. var Str:string;
  353. begin
  354.    if (Start = 0) and (Finish = 0) then
  355.       SLLGetStrFunc := _SLLGetNodeStr(SingleLL(P^),_SLLNodePtr(SingleLL(P^),Element),0)
  356.    else
  357.    begin
  358.       Str := copy(_SLLGetNodeStr(SingleLL(P^),_SLLNodePtr(SingleLL(P^),Element),0),Start,succ(Finish-Start));
  359.       if length(Str) < succ(Finish - Start) then
  360.          Str := PadLeft(Str,succ(Finish - Start),' ');
  361.       SLLGetStrFunc := Str;
  362.    end;
  363. end; { SLLGetStrFunc }
  364.  
  365. function SLLGetBitFunc(P:pointer;Pick:longint;BitPos:byte): boolean;
  366. {}
  367. begin
  368.    SLLGetBitFunc := SLLGetBit(_SLLNodePtr(SingleLL(P^),Pick),BitPos);
  369. end; { SLLGetBitFunc }
  370.  
  371. procedure SLLSetBitFunc(P:pointer;Pick:longint;BitPos:byte;On:boolean);
  372. {}
  373. begin
  374.    _SLLSetBit(SingleLL(P^),_SLLNodePtr(SingleLL(P^),Pick),BitPos,On);
  375. end; { SLLSetBitFunc }
  376.  
  377. function DLLGetStrFunc(P:pointer;Element,Start,Finish: longint): string;
  378. {}
  379. var Str:string;
  380. begin
  381.    Str := copy(DLLGetNodeStr(DLLNodePtr(Element),0,255),Start,succ(Finish-Start));
  382.    if length(Str) < succ(Finish - Start) then
  383.       Str := PadLeft(Str,succ(Finish - Start),' ');
  384.    DLLGetStrFunc := Str;
  385. end; { DLLGetStrFunc }
  386.  
  387. function DLLGetBitFunc(P:pointer;Pick:longint;BitPos:byte): boolean;
  388. {}
  389. begin
  390.    DLLGetBitFunc := DLLGetBit(DLLNodePtr(Pick),BitPos);
  391. end; { DLLGetBitFunc }
  392.  
  393. procedure DLLSetBitFunc(P:pointer;Pick:longint;BitPos:byte;On:boolean);
  394. {}
  395. begin
  396.    DLLSetBit(DLLNodePtr(Pick),BitPos,On);
  397. end; { DLLSetBitFunc }
  398.  
  399. procedure NoListCharHook(var K : word;var X,Y:byte);
  400. {}
  401. begin
  402. end; {NoListCharHook}
  403.  
  404. procedure NoListHindHook(ListDetails:ListCfgPtr);
  405. {}
  406. begin
  407. end; {NoListHindHook}
  408.  
  409. function ListDefaultSelectHook(ListDetails:ListCfgPtr):gAction;
  410. {}
  411. begin
  412.    with KeyVars do
  413.    begin
  414.       if (LastKey = 600)
  415.       or (LastKey = 27) then
  416.          ListDefaultSelectHook := Escaped
  417.       else if ((LastKey = 540) and (LastX <> 0))
  418.       or (LastKey = 13) then
  419.          ListDefaultSelectHook := Finished
  420.       else
  421.          ListDefaultSelectHook := None;
  422.    end
  423. end; {ListDefaultSelectHook}
  424.  
  425. procedure NoListColorHook(Pick:longint;Hi:boolean;  var Attr:byte);
  426. {}
  427. begin
  428. end; {NoListColorHook}
  429. {$IFDEF FOFF}
  430.    {$F-}
  431.    {$UNDEF FOFF}
  432. {$ENDIF}
  433.  
  434.                           {**********************}
  435.                           {**  Initialization  **}
  436.                           {**********************}
  437.  
  438.  
  439. procedure InitListCFG(var ListDetails: ListCfg);
  440. {}
  441. var
  442.    A: TintElement;
  443.    I: integer;
  444. begin
  445.    fillchar(Listdetails,sizeof(Listdetails),#0);
  446.    with Listdetails do
  447.    begin
  448.       DataSource := nil;
  449.       DataType := SourceUnknown;
  450.       X1 := 1;
  451.       Y1 := 1;
  452.       X2 := 20;
  453.       Y2 := 10;
  454.       TotalNodes := 0;
  455.       ActiveNode := 0;
  456.       TopNode := 0;
  457.       AllowTagging := false;
  458.       AllowTwoColors := false;
  459.       ChangeColorsWithTags := false;
  460.       IODispose := true;
  461.       InWindow := false;
  462.       Browsing := false;
  463.       ColWidth := 0;
  464.       LastColWidth := 0;
  465.       ColCount := 1;
  466.       RowCount := 1;
  467.       for A := FirstListCol to LastListCol do
  468.          Col[A] := Tint[A];
  469.       GetStr := DummyGetStr;
  470.       GetBit := DummyGetBit;
  471.       SetBit := DummySetBit;
  472.       CharHook := NoListCharHook;
  473.       HindHook := NoListHindHook;
  474.       SelectHook := ListDefaultSelectHook;
  475.       ColorHook := NoListColorHook;
  476.       WStyle := ListVars.WinStyle;
  477.       {header/footer stuff}
  478.       for I :=  1 to ListMaxHeaders do
  479.          Headers[I] := nil;
  480.       ScrollHeader := true;
  481.       for I :=  1 to ListMaxFooters do
  482.          Footers[I] := nil;
  483.       ScrollFooter := true;
  484.       {Form stuff}
  485.       ColumnLock := 0;
  486.       RowLock := 0;
  487.       StartingCol := 1;
  488.       LastCol := 255;
  489.       WriteHeadingsHook := NoListHindHook;
  490.       TabsArrayPtr := nil;
  491.       TabsArrayPos := 1;
  492.       TabsArrayDim := 0;
  493.    end;
  494. end; { InitListCFG }
  495.  
  496. procedure ListSetWin(var ListDetails: ListCfg; X1,Y1,X2,Y2:integer; Style:byte);
  497. {}
  498. begin
  499.    ListDetails.WX1 := X1;
  500.    ListDetails.WY1 := Y1;
  501.    ListDetails.WX2 := X2;
  502.    ListDetails.WY2 := Y2;
  503.    ListDetails.WStyle := Style;
  504. end; { ListSetWin }
  505.  
  506. procedure ListSetGaps(var ListDetails: ListCfg; LeftGap,RightGap,BotGap,TopGap: byte);
  507. {}
  508. begin
  509.    ListDetails.LeftGap := LeftGap;
  510.    ListDetails.RightGap := RightGap;
  511.    ListDetails.BotGap := BotGap;
  512.    ListDetails.TopGap := TopGap;
  513. end; { ListSetGaps }
  514.  
  515. procedure ListSetColor(var ListDetails: ListCfg; A:TintElement;C:byte);
  516. {}
  517. begin
  518.    if A in [FirstListCol..LastListCol] then
  519.       ListDetails.Col[A] := C;
  520. end; { ListSetColor }
  521.  
  522.                         {**************************}
  523.                         {**  Heading Management  **}
  524.                         {**************************}
  525.  
  526. procedure ListAssignHeader(var ListDetails: ListCfg; Line:byte; var Heading:string);
  527. {}
  528. begin
  529.    if (Line < 1) or (Line > ListMaxHeaders) then
  530.       ListSetError(1003)
  531.    else
  532.       Listdetails.Headers[Line] := @Heading;
  533. end; {ListAssignHeader}
  534.  
  535. procedure ListAssignFooter(var ListDetails: ListCfg; Line:byte; var Footnote:string);
  536. {}
  537. begin
  538.    if (Line < 1) or (Line > ListMaxFooters) then
  539.       ListSetError(1003)
  540.    else
  541.       Listdetails.Footers[Line] := @Footnote;
  542. end; {ListAssignFooter}
  543.  
  544. procedure ListRemoveHeader(var ListDetails: ListCfg; Line:byte);
  545. {}
  546. begin
  547.    if (Line < 1) or (Line > ListMaxHeaders) then
  548.       ListSetError(1003)
  549.    else
  550.       Listdetails.Headers[Line] := nil;
  551. end; {ListRemoveHeader}
  552.  
  553. procedure ListRemoveFooter(var ListDetails: ListCfg; Line:byte);
  554. {}
  555. begin
  556.    if (Line < 1) or (Line > ListMaxFooters) then
  557.       ListSetError(1003)
  558.    else
  559.       Listdetails.Footers[Line] := nil;
  560. end; {ListRemoveFooter}
  561.  
  562. procedure ListScrollHeader(var ListDetails: ListCfg; On:boolean);
  563. {}
  564. begin
  565.    ListDetails.ScrollHeader := On;
  566. end; {ListScrollHeader}
  567.  
  568. procedure ListScrollFooter(var ListDetails: ListCfg; On:boolean);
  569. {}
  570. begin
  571.    ListDetails.ScrollFooter := On;
  572. end; {ListScrollFooter}
  573.  
  574. procedure GListWriteScrollBar(var ListDetails: ListCfg; Status:gStatus);
  575. {}
  576. var A:byte;
  577. begin
  578.    with ListDetails do
  579.    begin
  580.       if TotalNodes > succ(Y2-Y1) then {need a scroll bar}
  581.       begin
  582.          if Status in [Activate,HiStatus] then
  583.             A := Col[ListScrollbarHi]
  584.          else
  585.             A := Col[ListScrollbarNorm];
  586.          WriteVScrollBar(X2,Y1,Y2,A,ActiveNode,TotalNodes);
  587.       end
  588.    end;
  589. end; { GListWriteScrollBar }
  590.  
  591. procedure GListWriteItem(var ListDetails: ListCfg; ItemNum:longint; Status:gStatus);
  592. {}
  593. var
  594.   A:byte;
  595.   Str:StrScreen;
  596. begin
  597.    with ListDetails do
  598.    begin
  599.       Str := GetStr(DataSource,ItemNum,1,X2-X1-2);
  600.       case Status of
  601.          Activate, HiStatus, NormStatus: begin
  602.             if (AllowTwoColors or ChangeColorsWithTags) and GetBit(DataSource,ItemNum,ColBit) then
  603.                A := Col[ListNorm2]
  604.             else
  605.                A := Col[ListNorm1];
  606.          end;
  607.          OffStatus: A := Col[ListOff]
  608.       end; {case}
  609.       if ItemNum = ActiveNode then
  610.       begin
  611.          Str := ListVars.ListLeft + Str + ListVars.ListRight;
  612.          (*
  613.          if (Status in [HiStatus,Activate,NormStatus]) then
  614.          *)
  615.          if (Status in [HiStatus,Activate,NormStatus]) then
  616.          begin
  617.             if (AllowTwoColors or ChangeColorsWithTags)
  618.             and (Status in [HiStatus,Activate])
  619.             and GetBit(DataSource,ItemNum,ColBit) then
  620.                A := Col[ListHi2]
  621.             else if Status = NormStatus then
  622.                A := Col[ListHiInActive]
  623.             else
  624.                A := Col[ListHi1];
  625.          end;
  626.       end
  627.       else
  628.          Str := replicate(length(ListVars.ListLeft),' ')+Str+replicate(length(ListVars.ListRight),' ');
  629.       Listdetails.ColorHook(ItemNum,ItemNum = ActiveNode,A);
  630.       WriteAT(X1,Y1+ItemNum-TopNode,A,Str);
  631.       if (Status in [HiStatus,Activate,NormStatus]) and (ItemNum = ActiveNode) then
  632.       begin
  633.          GListWriteScrollBar(Listdetails,Status);
  634.          if Status in [HiStatus,Activate] then
  635.             gotoxy(succ(X1),Y1+ItemNum-TopNode);
  636.       end;
  637.    end;
  638. end; { GListWriteItem }
  639.  
  640. procedure GListRefresh(var ListDetails: ListCfg; Status:gStatus);
  641. {Updates the list area}
  642. var I : longint;
  643. begin
  644.    with ListDetails do
  645.    begin
  646.       if (ActiveNode < TopNode)
  647.       or (ActiveNode > TopNode + Y2 -Y1) then
  648.       begin
  649.          If Y2 > Y1 then
  650.             TopNode := ActiveNode - (Y2 - Y1) div 2
  651.          else
  652.             TopNode := ActiveNode;
  653.       end;
  654.       for I := TopNode to TopNode + Y2 - Y1 do
  655.           GListWriteItem(ListDetails,I,Status);
  656.    end;
  657. end; { GListRefresh }
  658.  
  659.                      {****************************}
  660.                      {**  List Scrolling Logic  **}
  661.                      {****************************}
  662.  
  663. function ListScrollUp(var ListDetails: ListCfg): boolean;
  664. {Updates the ActiveNode and TopNode parameters and returns
  665.  true if TopNode is modified, i.e. if the list needs to be
  666.  refreshed}
  667. begin
  668.    ListScrollUp := false;
  669.    with ListDetails do
  670.    begin
  671.       if ActiveNode > TopNode then
  672.          dec(ActiveNode)
  673.       else if TopNode > 1 then
  674.       begin
  675.          dec(TopNode);
  676.          ActiveNode := TopNode;
  677.          ListScrollUp := true;
  678.       end;
  679.    end;
  680. end; {ListScrollUp}
  681.  
  682. function ListScrollDown(var ListDetails: ListCfg): boolean;
  683. {Updates the ActiveNode and TopNode parameters and returns
  684.  true if TopNode is modified, i.e. if the list needs to be
  685.  refreshed}
  686. begin
  687.    ListScrollDown := false;
  688.    with ListDetails do
  689.    begin
  690.       if ActiveNode < TotalNodes then
  691.       begin
  692.          if ActiveNode < TopNode + Y2 - Y1 then
  693.             inc(ActiveNode)
  694.          else
  695.          begin
  696.             inc(TopNode);
  697.             inc(ActiveNode);
  698.             ListScrollDown := true;
  699.          end;
  700.       end;
  701.    end;
  702. end; {ListScrollDown}
  703.  
  704. function ListScrollPgDn(var ListDetails: ListCfg): boolean;
  705. {Updates the ActiveNode and TopNode parameters and returns
  706.  true if TopNode is modified, i.e. if the list needs to be
  707.  refreshed}
  708. begin
  709.    with ListDetails do
  710.    begin
  711.       if ActiveNode < TotalNodes then
  712.       begin
  713.          ListScrollPgDn := true;
  714.          if ActiveNode + succ(Y2-Y1) > TotalNodes then
  715.             ActiveNode := TotalNodes
  716.          else
  717.          begin
  718.             inc(TopNode,succ(Y2-Y1));
  719.             inc(ActiveNode,succ(Y2-Y1));
  720.          end;
  721.       end
  722.       else
  723.          ListScrollPgDn := false;
  724.    end;
  725. end; {ListScrollPgDn}
  726.  
  727. function ListScrollPgUp(var ListDetails: ListCfg): boolean;
  728. {Updates the ActiveNode and TopNode parameters and returns
  729.  true if TopNode is modified, i.e. if the list needs to be
  730.  refreshed}
  731. begin
  732.    ListScrollPgUp := false;
  733.    with ListDetails do
  734.    begin
  735.       if ActiveNode > 1 then
  736.       begin
  737.          if TopNode > 1 then
  738.             ListScrollPgUp := true;
  739.          if TopNode - succ(Y2-Y1) < 1 then
  740.             TopNode := 1
  741.          else
  742.             dec(TopNode,succ(Y2-Y1));
  743.          if ActiveNode - succ(Y2-Y1) < 1 then
  744.             ActiveNode := 1
  745.          else
  746.             dec(ActiveNode,succ(Y2-Y1));
  747.       end;
  748.    end;
  749. end; {ListScrollPgUp}
  750.  
  751. function ListScrollHome(var ListDetails: ListCfg): boolean;
  752. {Updates the ActiveNode and TopNode parameters and returns
  753.  true if TopNode is modified, i.e. if the list needs to be
  754.  refreshed}
  755. begin
  756.    with ListDetails do
  757.    begin
  758.       ListScrollHome := (TopNode > 1);
  759.       TopNode := 1;
  760.       ActiveNode := 1;
  761.    end;
  762. end; {ListScrollHome}
  763.  
  764. function ListScrollEnd(var ListDetails: ListCfg): boolean;
  765. {Updates the ActiveNode and TopNode parameters and returns
  766.  true if TopNode is modified, i.e. if the list needs to be
  767.  refreshed}
  768. begin
  769.    with ListDetails do
  770.    begin
  771.       if TopNode + Y2 - Y1 < TotalNodes then
  772.       begin
  773.          ListScrollEnd := true;
  774.          TopNode := TotalNodes - (Y2 - Y1) ;
  775.       end
  776.       else
  777.          ListScrollEnd := false;
  778.       ActiveNode := TotalNodes;
  779.    end;
  780. end; {ListScrollEnd}
  781.  
  782. procedure ListMoveIt(var ListDetails: ListCfg; Direction: byte);
  783. {}
  784. var
  785.   Repaint: boolean;
  786.   OldAct: integer;
  787. begin
  788.    with ListDetails do
  789.    begin
  790.       OldAct := ActiveNode;
  791.       if ((Direction in [1,3,5]) and (ActiveNode = 1))
  792.       or ((Direction in [2,4,6]) and (ActiveNode = TotalNodes)) then
  793.          exit;
  794.       case Direction of
  795.         1: Repaint := ListScrollUp(ListDetails);
  796.         2: Repaint := ListScrollDown(ListDetails);
  797.         3: Repaint := ListScrollPgUp(ListDetails);
  798.         4: Repaint := ListScrollPgDn(ListDetails);
  799.         5: Repaint := ListScrollHome(ListDetails);
  800.         6: Repaint := ListScrollEnd(ListDetails);
  801.       end;
  802.       if Repaint then
  803.          GListRefresh(ListDetails,HiStatus)
  804.       else if OldAct <> ActiveNode then
  805.       begin
  806.          GListWriteItem(ListDetails,OldAct,HiStatus);
  807.          GListWriteItem(ListDetails,ActiveNode,HiStatus);
  808.       end;
  809.    end;
  810. end; { ListMoveIt }
  811.  
  812.                        {***************************}
  813.                        {**  List Mouse Handling  **}
  814.                        {***************************}
  815.  
  816. procedure ListMouseVScroll(var ListDetails: ListCfg);
  817. {}
  818. var
  819.   L,M,R: boolean;
  820.   X,Y,ElevatorY:byte;
  821.   WaitTime: integer;
  822.  
  823.   procedure ScrollUpOne;
  824.   {}
  825.   begin
  826.      with ListDetails do
  827.      repeat
  828.         MouseStatusWin(L,M,R,X,Y);
  829.         if (X = X2) and (Y = Y1) and L then
  830.            ListMoveIt(Listdetails,1);
  831.         DelayIt(L,InWindow,WaitTime);
  832.      until not L;
  833.   end; { ScrollUpOne }
  834.  
  835.   procedure ScrollDownOne;
  836.   {}
  837.   begin
  838.      with ListDetails do
  839.      repeat
  840.         MouseStatusWin(L,M,R,X,Y);
  841.         if (X = X2) and (Y = Y2) and L then
  842.            ListMoveIt(ListDetails,2);
  843.         DelayIt(L,InWindow,WaitTime);
  844.      until not L;
  845.   end; { ScrollDownOne }
  846.  
  847.   procedure ScrollUpward;
  848.   {}
  849.   begin
  850.      with ListDetails do
  851.      repeat
  852.         MouseStatusWin(L,M,R,X,Y);
  853.         if ActiveNode <> 1 then
  854.         begin
  855.            if (X = X2) and (Y >= Y1) and (Y <= ElevatorY) and L then
  856.               ListMoveIt(ListDetails,3);   {PgUp effect}
  857.            DelayIt(L,InWindow,WaitTime);
  858.         end;
  859.      until not L;
  860.   end; { ScrollUpward }
  861.  
  862.   procedure ScrollDownward;
  863.   {}
  864.   begin
  865.      with ListDetails do
  866.      repeat
  867.         MouseStatusWin(L,M,R,X,Y);
  868.         if ActiveNode <> TotalNodes then
  869.         begin
  870.            if (X = X2) and (Y <= Y2) and (Y >= ElevatorY) and L then
  871.               ListMoveIt(ListDetails,4);   {PgDn effect}
  872.            DelayIt(L,InWindow,WaitTime);
  873.         end;
  874.      until not L;
  875.   end; { ScrollDownward }
  876.  
  877.   procedure ScrollDragElevator;
  878.   {}
  879.   var
  880.     OldY:byte;
  881.     NewActive:longint;
  882.   begin
  883.      OldY := Y;
  884.      with ListDetails do
  885.      repeat
  886.         MouseStatusWin(L,M,R,X,Y);
  887.         if (X = X2) and (Y < Y2) and (Y > Y1) and (Y <> OldY) and L then
  888.         begin
  889.            OldY := Y;
  890.            if Y = succ(Y1) then
  891.               NewActive := 1
  892.            else if Y = pred(Y2) then
  893.               NewActive := TotalNodes
  894.            else
  895.               NewActive := TotalNodes * (Y - Y1) div (Y2-Y1);
  896.            if NewActive <> ActiveNode then
  897.            begin
  898.               ActiveNode := NewActive;
  899.               TopNode := NewActive;
  900.               GListRefresh(ListDetails,HiStatus);
  901.            end;
  902.            if WindowHasFocus then
  903.               WinDrawTop;
  904.         end;
  905.      until not L;
  906.   end; { ScrollElevator }
  907.  
  908. begin
  909.    with ListDetails do
  910.    begin
  911.       WaitTime := KeyVars.InitScrollDelay;
  912.       InWindow := WindowHasFocus;
  913.       repeat
  914.          MouseStatusWin(L,M,R,X,Y);
  915.          if L and (X = X2) then
  916.          begin
  917.             if Y = Y1 then
  918.                ScrollUpOne
  919.             else if Y = Y2 then
  920.                ScrollDownOne
  921.             else    {mouse pressed along scroll bar body}
  922.             begin
  923.                ElevatorY := GetVScrollBarElevator(Y1,Y2,ActiveNode,TotalNodes);
  924.                if ((Y = succ(Y1)) and (Y=ElevatorY) and (ActiveNode > 1))
  925.                or (Y > Y1) and (Y < ElevatorY) then
  926.                   ScrollUpward
  927.                else if ((Y = pred(Y2)) and (Y=ElevatorY)
  928.                         and
  929.                         (ActiveNode < TotalNodes)
  930.                        )
  931.                        or ((Y < Y2) and (Y > ElevatorY))  then
  932.                   ScrollDownward
  933.                else {user is dragging elevator}
  934.                   ScrollDragElevator;
  935.              end;
  936.          end;
  937.       until not L;
  938.       MouseRelease;
  939.    end;
  940. end; { ListMouseVScroll }
  941.  
  942. function ListOnTarget(var ListDetails: ListCfg;X,Y:byte): byte;
  943. {}
  944. begin
  945.    with ListDetails do
  946.    begin
  947.       if  (X >= X1) and (X <= X2)
  948.       and (Y >= Y1) and (Y <= Y2)
  949.       and (Y <= Y1 + TotalNodes - pred(TopNode)) then
  950.       begin
  951.          ListOnTarget := Y - Y1 + TopNode
  952.       end
  953.       else
  954.          ListOnTarget := 0;
  955.    end;
  956. end; { OnTarget }
  957.  
  958. procedure ListMouseSelect(var ListDetails: ListCfg);
  959. {Called when mouse pressed on field and held down}
  960. var
  961.   L,M,R: boolean;
  962.   X,Y:byte;
  963.   OldAct,
  964.   NewAct: integer;
  965. begin
  966.    with ListDetails do
  967.    repeat
  968.       MouseStatusWin(L,M,R,X,Y);
  969.       if L then
  970.       begin
  971.          OldAct := ActiveNode;
  972.          NewAct := ListOnTarget(Listdetails,X,Y);
  973.          if (NewAct <> 0) and (NewAct <> OldAct) then
  974.          begin
  975.             ActiveNode := NewAct;
  976.             GListWriteItem(ListDetails,OldAct,HiStatus);
  977.             GListWriteItem(ListDetails,ActiveNode,HiStatus);
  978.             if WindowHasFocus then
  979.                WinDrawTop;
  980.          end;
  981.          (*
  982.          if NewAct = 0 then
  983.             CursorOff
  984.          else
  985.             CursorOn;
  986.          *)
  987.       end;
  988.    until not L;
  989.    MouseRelease;
  990. end; {ListMouseSelect}
  991.  
  992.                            {********************}
  993.                            {**  Key Handling  **}
  994.                            {********************}
  995.  
  996. procedure GListProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  997. {}
  998. begin
  999.    with ListDetails do
  1000.    begin
  1001.       CharHook(K,X,Y); {call user hook}
  1002.       if MakeLocal then
  1003.          if IsWinKey(K,X,Y) then
  1004.             WinProcessKey(K,X,Y);
  1005.       if (K = 500) or (K = 540) then
  1006.       begin
  1007.          if MakeLocal then {convert to local coords}
  1008.          begin
  1009.             X := WinLocalX(0,X);
  1010.             Y := WinLocalY(0,Y);
  1011.          end;
  1012.          if K = 500 then
  1013.          begin
  1014.             if (X = X2) and (TotalNodes > succ(Y2-Y1)) then
  1015.                ListMouseVScroll(Listdetails)
  1016.             else
  1017.                ListMouseSelect(Listdetails);
  1018.          end
  1019.          else if ListOnTarget(Listdetails,X,Y) <> 0 then
  1020.            K := 540;   {double click}
  1021.       end
  1022.       else
  1023.       case K of
  1024.          331,328: ListMoveIt(ListDetails,1);
  1025.          333,336: ListMoveIt(ListDetails,2);
  1026.          329: ListMoveIt(ListDetails,3);
  1027.          337: ListMoveIt(ListDetails,4);
  1028.          327: ListMoveIt(ListDetails,5);
  1029.          335: ListMoveIt(ListDetails,6);
  1030.       end; {case}
  1031.       LastKey := K;
  1032.       HindHook(@ListDetails);
  1033.    end;
  1034. end; { GListProcessKey }
  1035.  
  1036.                              {***************}
  1037.                              {**  ListWin  **}
  1038.                              {***************}
  1039.  
  1040. function RunListStrLL(ListSource:StringLL;Tit:StrScreen):longint;
  1041. {}
  1042. var
  1043.   Settings: ListCfg;
  1044.   Handle: integer;
  1045.  
  1046.    procedure SetWindow;
  1047.    {}
  1048.    begin
  1049.       with ListVars do
  1050.       begin
  1051.          Handle := WinCreate(WX1,WY1,WX2,WY2,WinStyle);
  1052.          WinSetType(Handle,WMove);  {don't allow strectch -- since its used in forms}
  1053.          WinSetTitle(Handle,Tit);
  1054.          WinSetShowNum(Handle,false);
  1055.          WinSetColor(Handle,WinBorder,Tint[ListBorder1]);
  1056.          WinSetColor(Handle,WinBorder3DOut,Tint[ListBorder1]);
  1057.          WinSetColor(Handle,WinBorder3DIn,Tint[ListBorder2]);
  1058.          WinSetColor(Handle,WinBorderOff,Tint[ListBorderOff]);
  1059.          WinSetColor(Handle,WinIcons,Tint[ListIcons]);
  1060.          WinSetColor(Handle,WinBody,Tint[ListNorm1]);
  1061.          WinSetColor(Handle,WinTitle,Tint[ListTitle]);
  1062.          WinPaint(Handle);
  1063.       end;
  1064.    end; {SetWindow}
  1065.  
  1066. begin
  1067.    InitListCFG(Settings);
  1068.    with Settings do
  1069.    begin
  1070.       TotalNodes := ListSource.TotalNodes;
  1071.       ActiveNode := ListSource.ActiveNode;
  1072.       TopNode := ListSource.TopNode;
  1073.       DataSource := @ListSource;
  1074.       DataType := SourceStrLL;
  1075.       GetStr := SLGetStr;
  1076.       X2 := ListVars.WX2-ListVars.WX1-1-2*ord(WStyle in [7,8]);
  1077.       Y2 := ListVars.WY2-ListVars.WY1-1;
  1078.       InWindow := true;
  1079.    end;
  1080.    CalcColRow(Settings);
  1081.    SetWindow;
  1082.    WinDisplay(Handle);
  1083.    GListRefresh(Settings,HiStatus);
  1084.    WinDrawAll;
  1085.    with Settings do
  1086.    with KeyVars do
  1087.    repeat
  1088.       GetInput;
  1089.       GListProcessKey(Settings,LastKey,LastX,LastY,true);
  1090.       if (LastKey = 600)
  1091.       or (LastKey = 27)
  1092.       or ((LastKey = 540) and (LastX <> 0))
  1093.       or (LastKey = 13) then
  1094.       begin
  1095.          LastAction := SelectHook(@Settings);
  1096.          if LastAction = Refresh then
  1097.          begin
  1098.             TotalNodes := StringLL(dataSource^).TotalNodes;
  1099.             if (ActiveNode > TotalNodes) or (TopNode > TotalNodes) then
  1100.             begin
  1101.                ActiveNode := 1;
  1102.                TopNode := 1;
  1103.             end;
  1104.             GListRefresh(Settings,HiStatus);
  1105.          end;
  1106.       end
  1107.       else
  1108.          LastAction := none;
  1109.       WinDrawAll;
  1110.    until LastAction in [Stop1..Escaped];
  1111.    WinDispose(Handle);
  1112.    MouseRelease;
  1113.    ListVars.LastActiveItem := Settings.ActiveNode;
  1114.    if KeyVars.LastKey = 27 then
  1115.       RunListStrLL := 0
  1116.    else
  1117.       RunListStrLL := Settings.ActiveNode;
  1118. end; { RunListStrLL }
  1119.  
  1120.                {********************************************}
  1121.                {**       B R O W S I N G   L I S T S      **}
  1122.                {********************************************}
  1123. procedure SetInnerDimensions(var ListDetails: ListCfg);
  1124. {Asseses the window dimensions and sets the list coordinates
  1125.  X1..Y2 based on the window style and the gapxxx settings}
  1126. var
  1127.    Counter,
  1128.    I: integer;
  1129. begin
  1130.    with ListDetails do
  1131.    begin
  1132.       X1 := 1 + LeftGap;
  1133.       Y1 := 1 + TopGap;
  1134.       X2 := WX2-succ(WX1)-2*ord(WStyle in [7,8]) - RightGap;
  1135.       Y2 := WY2-succ(WY1) - BotGap;
  1136.       {now adjust for the headers and footers}
  1137.       Counter := 0;
  1138.       for I := 1 to ListMaxHeaders do
  1139.          inc(Counter,ord(Listdetails.Headers[I] <> nil));
  1140.       inc(Y1,Counter);
  1141.       Counter := 0;
  1142.       for I := 1 to ListMaxFooters do
  1143.          inc(Counter,ord(Listdetails.Footers[I] <> nil));
  1144.       dec(Y2,Counter);
  1145.       if Y2 <= Y1 then
  1146.          Y2 := Y1;
  1147.    end;
  1148. end; { SetInnerDimensions }
  1149.  
  1150. procedure RefreshHeadFoot(var ListDetails: ListCfg);
  1151. {}
  1152. var
  1153.    Counter,
  1154.    I: integer;
  1155.    TempStr: string;
  1156.    W,X: byte;
  1157.  
  1158. begin
  1159.    with Listdetails do
  1160.    begin
  1161.       Counter := 0;
  1162.       if Scrollheader then
  1163.          X := StartingCol
  1164.       else
  1165.          X := 1;
  1166.       W := (X2-X1)-ord(TotalNodes > succ(Y2-Y1));
  1167.       for I := 1 to ListMaxHeaders do
  1168.       begin
  1169.          if Listdetails.Headers[I] <> nil then
  1170.          begin
  1171.             inc(Counter);
  1172.             TempStr := copy(Listdetails.Headers[I]^,X,W);
  1173.             if (TempStr <> '') and (TempStr[1] = '^') then
  1174.             begin
  1175.                delete(TempStr,1,1);
  1176.                WriteBetween(succ(leftGap),X2-X1-RightGap,TopGap+Counter,Tint[ListHeaders],TempStr);
  1177.             end
  1178.             else
  1179.                WriteAT(succ(leftGap),TopGap+Counter,Tint[ListHeaders],padleft(TempStr,W,' '));
  1180.          end;
  1181.       end;
  1182.       Counter := 0;
  1183.       if ScrollFooter then
  1184.          X := StartingCol
  1185.       else
  1186.          X := 1;
  1187.       for I := 1 to ListMaxFooters do
  1188.       begin
  1189.          if Listdetails.Footers[I] <> nil then
  1190.          begin
  1191.             inc(Counter);
  1192.             TempStr := copy(Listdetails.Footers[I]^,X,W);
  1193.             if (TempStr <> '') and (TempStr[1] = '^') then
  1194.             begin
  1195.                delete(TempStr,1,1);
  1196.                WriteBetween(succ(leftGap),X2-X1-RightGap,Y2+Counter,Tint[ListHeaders],TempStr);
  1197.             end
  1198.             else
  1199.                WriteAT(succ(leftGap),Y2+Counter,Tint[ListHeaders],padleft(TempStr,W,' '));
  1200.          end;
  1201.       end;
  1202.    end;
  1203. end; {RefreshHeadFoot}
  1204.  
  1205. procedure BrowseRefresh(var ListDetails: ListCfg);
  1206. {Updates the list area}
  1207. var
  1208.    I : longint;
  1209.    A:byte;
  1210.    Str:StrScreen;
  1211.    HScrollBarVisible,
  1212.    VScrollBarVisible: boolean;
  1213. begin
  1214.    with ListDetails do
  1215.    begin
  1216.       VScrollbarVisible := TotalNodes > succ(Y2-Y1);
  1217.       HScrollbarVisible := LastCol > succ(X2-X1);
  1218.       for I := TopNode to TopNode + Y2 - Y1 - ord(HScrollbarVisible) do
  1219.       begin
  1220.          Str := GetStr(DataSource,I,StartingCol,StartingCol + (X2-X1)-ord(VScrollbarVisible));
  1221.          if (AllowTwoColors or ChangeColorsWithTags) and GetBit(DataSource,I,ColBit) then
  1222.             A := Col[ListNorm2]
  1223.          else
  1224.             A := Col[ListNorm1];
  1225.          ColorHook(I,false,A);
  1226.          WriteAT(X1,Y1+I-TopNode,A,Str);
  1227.       end;
  1228.       if VScrollBarVisible then
  1229.       begin
  1230.          if (TopNode = TotalNodes) or (TopNode = 1) then
  1231.             WriteVScrollBar(X2,Y1,Y2-ord(HScrollbarVisible),A,TopNode,TotalNodes)
  1232.          else
  1233.             WriteVScrollBar(X2,Y1,Y2-ord(HScrollbarVisible),A,TopNode + (Y2-Y1) ,TotalNodes);
  1234.       end;
  1235.       if HScrollBarVisible then
  1236.       begin
  1237.          if (StartingCol = LastCol) or (StartingCol = 1) then
  1238.             WriteHScrollBar(X1,X2-ord(VScrollbarVisible),Y2,Col[ListNorm1],StartingCol,LastCol)
  1239.          else
  1240.             WriteHScrollBar(X1,X2-ord(VScrollbarVisible),Y2,Col[ListNorm1],StartingCol + (X2-X1) ,LastCol);
  1241.       end;
  1242.    end;
  1243. end; { BrowseRefresh }
  1244.  
  1245. procedure BrowseWindowStretch(var Listdetails: ListCfg);
  1246. {Called when user stretches the window}
  1247. var
  1248.    WP: WStructurePtr;
  1249. begin
  1250.    {First set the listdetails to reflect the revised window dimensions}
  1251.    WP := WinPtr(0); {top window}
  1252.    with Listdetails do
  1253.    begin
  1254.       WX1 := WP^.X;
  1255.       WY1 := WP^.Y;
  1256.       WX2 := WX1 + pred(WP^.Width);
  1257.       WY2 := WY1 + pred(WP^.Depth);
  1258.    end;
  1259.    SetInnerDimensions(Listdetails);
  1260.    RefreshHeadFoot(Listdetails);
  1261.    BrowseRefresh(ListDetails);
  1262. end; {BrowseWindowStretch}
  1263.  
  1264. procedure BrowseMoveIt(var ListDetails: ListCfg; Direction: byte);
  1265. {Moves in a specified direction and repaints the list}
  1266. begin
  1267.    with ListDetails do
  1268.    begin
  1269.       if ((Direction in [1,3,5]) and (TopNode = 1))
  1270.       or ((Direction in [7,9]) and (StartingCol = LastCol))
  1271.       or ((Direction in [8,10]) and (StartingCol = 1))
  1272.       or ((Direction in [2,4,6]) and (TopNode = TotalNodes)) then
  1273.          exit;
  1274.       case Direction of
  1275.         1: begin
  1276.            dec(TopNode);
  1277.            BrowseRefresh(ListDetails);
  1278.         end;
  1279.         2: if TopNode < TotalNodes then {down one}
  1280.         begin
  1281.            inc(TopNode);
  1282.            BrowseRefresh(ListDetails);
  1283.         end;
  1284.         3: begin {PgUp}
  1285.            if TopNode - (Y2 - Y1) - ord(LastCol > succ(X2-X1)) < 1 then
  1286.                TopNode := 1
  1287.             else
  1288.                dec(TopNode,Y2 - Y1 - ord(LastCol > succ(X2-X1)));
  1289.             BrowseRefresh(ListDetails);
  1290.         end;
  1291.         4: begin {PgDn}
  1292.            if TopNode + (Y2 - Y1) - ord(LastCol > succ(X2-X1)) > TotalNodes then
  1293.               TopNode := TotalNodes
  1294.            else
  1295.               inc(TopNode,Y2 - Y1 - ord(LastCol > succ(X2-X1)));
  1296.            BrowseRefresh(ListDetails);
  1297.         end;
  1298.         5: begin {Ctrl-PgUp}
  1299.            TopNode := 1;
  1300.            BrowseRefresh(ListDetails);
  1301.         end;
  1302.         6: begin
  1303.            TopNode := TotalNodes;
  1304.            BrowseRefresh(ListDetails);
  1305.         end;
  1306.         7: begin
  1307.            inc(StartingCol);
  1308.            if Scrollheader or ScrollFooter then
  1309.               RefreshHeadFoot(Listdetails);
  1310.            BrowseRefresh(ListDetails);
  1311.         end;
  1312.         8: begin
  1313.            dec(StartingCol);
  1314.            if Scrollheader or ScrollFooter then
  1315.               RefreshHeadFoot(Listdetails);
  1316.            BrowseRefresh(ListDetails);
  1317.         end;
  1318.         9: begin
  1319.            if StartingCol + X2 - X1 - ord(TotalNodes > succ(Y2-Y1)) > LastCol then
  1320.               StartingCol := LastCol
  1321.            else
  1322.               inc(StartingCol,X2 - X1 - ord(TotalNodes > succ(Y2-Y1)));
  1323.            if Scrollheader or ScrollFooter then
  1324.               RefreshHeadFoot(Listdetails);
  1325.            BrowseRefresh(ListDetails);
  1326.         end;
  1327.         10: begin
  1328.            if StartingCol - (X2 - X1) - ord(TotalNodes > succ(Y2-Y1)) < 1 then
  1329.               StartingCol := 1
  1330.            else
  1331.               dec(StartingCol,X2 - X1 - ord(TotalNodes > succ(Y2-Y1)));
  1332.            if Scrollheader or ScrollFooter then
  1333.               RefreshHeadFoot(Listdetails);
  1334.            BrowseRefresh(ListDetails);
  1335.         end;
  1336.       end;
  1337.    end;
  1338. end; { BrowseMoveIt }
  1339.  
  1340. procedure BrowseMouseVScroll(var ListDetails: ListCfg);
  1341. {}
  1342. var
  1343.   L,M,R: boolean;
  1344.   X,Y,ElevatorY:byte;
  1345.   WaitTime: integer;
  1346.  
  1347.   procedure ScrollUpOne;
  1348.   {}
  1349.   begin
  1350.      with ListDetails do
  1351.      repeat
  1352.         MouseStatusWin(L,M,R,X,Y);
  1353.         if (X = X2) and (Y = Y1) and L then
  1354.            BrowseMoveIt(Listdetails,1);
  1355.         DelayIt(L,InWindow,WaitTime);
  1356.      until not L;
  1357.   end; { ScrollUpOne }
  1358.  
  1359.   procedure ScrollDownOne;
  1360.   {}
  1361.   begin
  1362.      with ListDetails do
  1363.      repeat
  1364.         MouseStatusWin(L,M,R,X,Y);
  1365.         if (X = X2) and (Y = Y2 - ord(LastCol > succ(X2-X1))) and L then
  1366.            BrowseMoveIt(ListDetails,2);
  1367.         DelayIt(L,InWindow,WaitTime);
  1368.      until not L;
  1369.   end; { ScrollDownOne }
  1370.  
  1371.   procedure ScrollUpward;
  1372.   {}
  1373.   begin
  1374.      with ListDetails do
  1375.      repeat
  1376.         MouseStatusWin(L,M,R,X,Y);
  1377.         if TopNode <> 1 then
  1378.         begin
  1379.            if (X = X2) and (Y >= Y1) and (Y <= ElevatorY) and L then
  1380.               BrowseMoveIt(ListDetails,3);   {PgUp effect}
  1381.            DelayIt(L,InWindow,WaitTime);
  1382.         end;
  1383.      until not L;
  1384.   end; { ScrollUpward }
  1385.  
  1386.   procedure ScrollDownward;
  1387.   {}
  1388.   begin
  1389.      with ListDetails do
  1390.      repeat
  1391.         MouseStatusWin(L,M,R,X,Y);
  1392.         if TopNode <> TotalNodes then
  1393.         begin
  1394.            if (X = X2) and (Y <= Y2) and (Y >= ElevatorY) and L then
  1395.               BrowseMoveIt(ListDetails,4);   {PgDn effect}
  1396.            DelayIt(L,InWindow,WaitTime);
  1397.         end;
  1398.      until not L;
  1399.   end; { ScrollDownward }
  1400.  
  1401.   procedure ScrollDragElevator;
  1402.   {}
  1403.   var
  1404.     OldY:byte;
  1405.     NewActive:longint;
  1406.   begin
  1407.      OldY := Y;
  1408.      with ListDetails do
  1409.      repeat
  1410.         MouseStatusWin(L,M,R,X,Y);
  1411.         if (X = X2) and (Y < Y2 - ord(LastCol > succ(X2-X1))) and (Y > Y1) and (Y <> OldY) and L then
  1412.         begin
  1413.            OldY := Y;
  1414.            if Y = succ(Y1) then
  1415.               NewActive := 1
  1416.            else if Y = pred(Y2) - ord(LastCol > succ(X2-X1))  then
  1417.               NewActive := TotalNodes
  1418.            else
  1419.               NewActive := (TotalNodes * (Y - Y1) div (Y2-Y1)) - (Y2-Y1);
  1420.            if NewActive <> TopNode then
  1421.            begin
  1422.               TopNode := NewActive;
  1423.               BrowseRefresh(ListDetails);
  1424.            end;
  1425.            if WindowHasFocus then
  1426.               WinDrawTop;
  1427.         end;
  1428.      until not L;
  1429.   end; { ScrollElevator }
  1430.  
  1431. begin
  1432.    with ListDetails do
  1433.    begin
  1434.       WaitTime := KeyVars.InitScrollDelay;
  1435.       InWindow := WindowHasFocus;
  1436.       repeat
  1437.          MouseStatusWin(L,M,R,X,Y);
  1438.          if L and (X = X2) then
  1439.          begin
  1440.             if Y = Y1 then
  1441.                ScrollUpOne
  1442.             else if Y = Y2 - ord(LastCol > succ(X2-X1)) then
  1443.                ScrollDownOne
  1444.             else    {mouse pressed along scroll bar body}
  1445.             begin
  1446.                ElevatorY := GetVScrollBarElevator(Y1,Y2,TopNode,TotalNodes);
  1447.                if ((Y = succ(Y1)) and (Y=ElevatorY) and (TopNode > 1))
  1448.                or (Y > Y1) and (Y < ElevatorY) then
  1449.                   ScrollUpward
  1450.                else if ((Y = pred(Y2) - ord(LastCol > succ(X2-X1))) and (Y=ElevatorY)
  1451.                         and
  1452.                         (TopNode < TotalNodes)
  1453.                        )
  1454.                        or ((Y < Y2 - ord(LastCol > succ(X2-X1))) and (Y > ElevatorY))  then
  1455.                   ScrollDownward
  1456.                else {user is dragging elevator}
  1457.                   ScrollDragElevator;
  1458.              end;
  1459.          end
  1460.          else
  1461.             MouseRelease;
  1462.       until not L;
  1463.       MouseRelease;
  1464.    end;
  1465. end; { BrowseMouseVScroll }
  1466.  
  1467. procedure BrowseMouseHScroll(var ListDetails: ListCfg);
  1468. {}
  1469. var
  1470.   L,M,R: boolean;
  1471.   X,Y,ElevatorX:byte;
  1472.   WaitTime: integer;
  1473.  
  1474.   procedure ScrollLeftOne;
  1475.   {}
  1476.   begin
  1477.      with ListDetails do
  1478.      repeat
  1479.         MouseStatusWin(L,M,R,X,Y);
  1480.         if (X = X1) and (Y = Y2) and L then
  1481.            BrowseMoveIt(Listdetails,8);
  1482.         DelayIt(L,InWindow,WaitTime);
  1483.      until not L;
  1484.   end; { ScrollLeftOne }
  1485.  
  1486.   procedure ScrollRightOne;
  1487.   {}
  1488.   begin
  1489.      with ListDetails do
  1490.      repeat
  1491.         MouseStatusWin(L,M,R,X,Y);
  1492.         if (X = X2 - ord(TotalNodes > succ(Y2-Y1))) and (Y = Y2) and L then
  1493.            BrowseMoveIt(ListDetails,7);
  1494.         DelayIt(L,InWindow,WaitTime);
  1495.      until not L;
  1496.   end; { ScrollRightOne }
  1497.  
  1498.   procedure ScrollLeftward;
  1499.   {}
  1500.   begin
  1501.      with ListDetails do
  1502.      repeat
  1503.         MouseStatusWin(L,M,R,X,Y);
  1504.         if StartingCol <> 1 then
  1505.         begin
  1506.            if (X >= X1) and (X <= ElevatorX) and (Y = Y2) and L then
  1507.               BrowseMoveIt(ListDetails,10);
  1508.            DelayIt(L,InWindow,WaitTime);
  1509.         end;
  1510.      until not L;
  1511.   end; { ScrollLeftward }
  1512.  
  1513.   procedure ScrollRightward;
  1514.   {}
  1515.   begin
  1516.      with ListDetails do
  1517.      repeat
  1518.         MouseStatusWin(L,M,R,X,Y);
  1519.         if TopNode <> TotalNodes then
  1520.         begin
  1521.            if (X <= X2) and (X >= ElevatorX) and (Y = Y2) and L then
  1522.               BrowseMoveIt(ListDetails,9);
  1523.            DelayIt(L,InWindow,WaitTime);
  1524.         end;
  1525.      until not L;
  1526.   end; { ScrollRightward }
  1527.  
  1528.   procedure ScrollDragElevator;
  1529.   {}
  1530.   var
  1531.     OldX:byte;
  1532.     NewActive:longint;
  1533.   begin
  1534.      OldX := X;
  1535.      with ListDetails do
  1536.      repeat
  1537.         MouseStatusWin(L,M,R,X,Y);
  1538.         if (Y = Y2) and (X < X2 - ord(TotalNodes > succ(Y2-Y1))) and (X > X1) and (X <> OldX) and L then
  1539.         begin
  1540.            OldX := X;
  1541.            if X = succ(X1) then
  1542.               NewActive := 1
  1543.            else if X = pred(X2) - ord(TotalNodes > succ(Y2-Y1))  then
  1544.               NewActive := LastCol
  1545.            else
  1546.               NewActive := (lastCol * (X - X1) div (X2-X1)) - (X2-X1);
  1547.            if NewActive <> StartingCol then
  1548.            begin
  1549.               StartingCol := NewActive;
  1550.               if Scrollheader or ScrollFooter then
  1551.                  RefreshHeadFoot(Listdetails);
  1552.               BrowseRefresh(ListDetails);
  1553.            end;
  1554.            if WindowHasFocus then
  1555.               WinDrawTop;
  1556.         end;
  1557.      until not L;
  1558.   end; { ScrollElevator }
  1559.  
  1560. begin
  1561.    with ListDetails do
  1562.    begin
  1563.       WaitTime := KeyVars.InitScrollDelay;
  1564.       InWindow := WindowHasFocus;
  1565.       repeat
  1566.          MouseStatusWin(L,M,R,X,Y);
  1567.          if L and (Y = Y2) then
  1568.          begin
  1569.             if X = X1 then
  1570.                ScrollLeftOne
  1571.             else if X = X2 - ord(TotalNodes > succ(Y2-Y1)) then
  1572.                ScrollRightOne
  1573.             else    {mouse pressed along scroll bar body}
  1574.             begin
  1575.                ElevatorX := GetHScrollBarElevator(X1,X2- ord(TotalNodes > succ(Y2-Y1)),StartingCol,LastCol);
  1576.                if ((X = succ(X1)) and (X=ElevatorX) and (StartingCol > 1))
  1577.                or (X > X1) and (X < ElevatorX) then
  1578.                   ScrollLeftward
  1579.                else if ((X = pred(X2) - ord(TotalNodes > succ(Y2-Y1))) and (X=ElevatorX)
  1580.                         and
  1581.                         (StartingCol < LastCol)
  1582.                        )
  1583.                        or ((X < X2 - ord(TotalNodes > succ(Y2-Y1))) and (X > ElevatorX))  then
  1584.                   ScrollRightward
  1585.                else {user is dragging elevator}
  1586.                   ScrollDragElevator;
  1587.              end;
  1588.          end
  1589.          else
  1590.             MouseRelease;
  1591.       until not L;
  1592.       MouseRelease;
  1593.    end;
  1594. end; { BrowseMouseHScroll }
  1595.  
  1596. procedure BrowseProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte; MakeLocal: boolean);
  1597. {}
  1598.  
  1599. begin
  1600.    with ListDetails do
  1601.    begin
  1602.       CharHook(K,X,Y); {call user hook}
  1603.       if MakeLocal then
  1604.          if IsWinKey(K,X,Y) then
  1605.             WinProcessKey(K,X,Y);
  1606.       K := CapitalWord(K);
  1607.       if (K = 500) then
  1608.       begin
  1609.          if MakeLocal then {convert to local coords}
  1610.          begin
  1611.             X := WinLocalX(0,X);
  1612.             Y := WinLocalY(0,Y);
  1613.          end;
  1614.          if (X = X2) and (TotalNodes > succ(Y2-Y1)) then
  1615.             BrowseMouseVScroll(Listdetails)
  1616.          else if (Y = Y2) and (LastCol > succ(X2-X1)) then
  1617.             BrowseMouseHScroll(Listdetails)
  1618.          else
  1619.             MouseRelease;
  1620.       end
  1621.       else
  1622.       case K of
  1623.          328: BrowseMoveIt(Listdetails,1);
  1624.          336: BrowseMoveIt(Listdetails,2);
  1625.          329: BrowseMoveIt(Listdetails,3);
  1626.          337: BrowseMoveIt(Listdetails,4);
  1627.          327: if StartingCol > 1 then
  1628.          begin
  1629.             StartingCol := 1;
  1630.             if Scrollheader or ScrollFooter then
  1631.                RefreshHeadFoot(Listdetails);
  1632.             BrowseRefresh(ListDetails);
  1633.          end;
  1634.          335: if StartingCol < LastCol then
  1635.          begin
  1636.             StartingCol := LastCol;
  1637.             if Scrollheader or ScrollFooter then
  1638.                RefreshHeadFoot(Listdetails);
  1639.             BrowseRefresh(ListDetails);
  1640.          end;
  1641.          388: BrowseMoveIt(Listdetails,5);
  1642.          374: BrowseMoveIt(Listdetails,6);
  1643.          331: BrowseMoveIt(Listdetails,8);
  1644.          333: BrowseMoveIt(Listdetails,7);
  1645.          9:   BrowseMoveIt(Listdetails,9);
  1646.          271: BrowseMoveIt(Listdetails,10);
  1647.          27,600:  LastAction := Escaped;
  1648.          602: if WindowHasFocus then
  1649.                  BrowseWindowStretch(Listdetails);
  1650.       end; {case}
  1651.       LastKey := K;
  1652.       HindHook(@ListDetails);
  1653.    end;
  1654. end; { BrowseProcessKey }
  1655.  
  1656. function BrowseCreateWin(WX1,WY1,WX2,WY2,WStyle:byte):byte;
  1657. {}
  1658. begin
  1659.    BrowseCreateWin := WinCreate(WX1,WY1,WX2,WY2,WStyle);
  1660. end; { BrowseCreateWin }
  1661.  
  1662. procedure DisplayBrowseEngine(Handle:integer; var ListDetails: ListCfg;Tit:StrScreen);
  1663. {}
  1664.  
  1665.    procedure SetWindow;
  1666.    {}
  1667.    begin
  1668.       with ListDetails do
  1669.       with ListVars do
  1670.       begin
  1671.          WinSetType(Handle,WrapWinType);
  1672.          WinSetTitle(Handle,Tit);
  1673.          WinSetShowNum(Handle,false);
  1674.          WinSetColor(Handle,WinBorder,Listdetails.Col[ListBorder1]);
  1675.          WinSetColor(Handle,WinBorder3DOut,Listdetails.Col[ListBorder1]);
  1676.          WinSetColor(Handle,WinBorder3dIn,Listdetails.Col[ListBorder2]);
  1677.          WinSetColor(Handle,WinBorderOff,Listdetails.Col[ListBorderOff]);
  1678.          WinSetColor(Handle,WinIcons,Listdetails.Col[ListIcons]);
  1679.          WinSetColor(Handle,WinBody,Listdetails.Col[ListNorm1]);
  1680.          WinSetColor(Handle,WinTitle,Listdetails.Col[ListTitle]);
  1681.          if ListDetails.ColWidth <> 0 then
  1682.             WinSetMinSize(Handle,ListDetails.ColWidth+2+2*ord(WinStyle in [7,8]),WinVars.MinDepth);
  1683.          WinPaint(Handle);
  1684.       end;
  1685.    end; {SetWindow}
  1686.  
  1687. begin
  1688.    SetWindow;
  1689.    WinDisplay(Handle);
  1690.    RefreshHeadFoot(Listdetails);
  1691.    BrowseRefresh(ListDetails);
  1692.    ListDetails.HindHook(@ListDetails); {call it once after window is created}
  1693. end; { DisplayBrowseEngine }
  1694.  
  1695. procedure RunBrowse(var ListDetails: ListCfg;Tit:StrScreen);
  1696. {}
  1697. var
  1698.    Handle: integer;
  1699. begin
  1700.    with ListDetails do
  1701.    begin
  1702.       if WX1 = 0 then  {user hasn't set the window}
  1703.       begin
  1704.          WX1 := ListVars.WX1;
  1705.          WY1 := ListVars.WY1;
  1706.          WX2 := ListVars.WX2;
  1707.          WY2 := ListVars.WY2;
  1708.       end;
  1709.       Handle := BrowseCreateWin(WX1,WY1,WX2,WY2,WStyle);
  1710.       if Handle = 0 then
  1711.          ListSetError(1004);
  1712.    end;
  1713.    SetInnerDimensions(Listdetails);
  1714.    ListDetails.InWindow := true;
  1715.    DisplayBrowseEngine(Handle,Listdetails,Tit);
  1716.    WinDrawAll;
  1717.    with Listdetails do
  1718.    with KeyVars do
  1719.    repeat
  1720.       GetInput;
  1721.       BrowseProcessKey(ListDetails,LastKey,LastX,LastY,true);
  1722.       WinDrawAll;
  1723.    until LastAction in [Stop1..Escaped];
  1724.    WinDispose(Handle);
  1725.    MouseRelease;
  1726. end; {RunBrowse}
  1727.  
  1728. procedure RunBrowseFile(Fname:PathStr;Tit:StrScreen);
  1729. {}
  1730. var
  1731.    DLL: DoubleLL;
  1732.    Result: integer;
  1733.    Config: ListCfg;
  1734. begin
  1735.    InitDLLStr(DLL);
  1736.    DLLSetActiveList(DLL);
  1737.    Result := DLLLoadFromFile(Fname);
  1738.    case Result of
  1739.       1,2: ListSetError(1001);
  1740.       3: ListSetError(1002);
  1741.       else
  1742.       begin
  1743.          InitListCFG(Config);
  1744.          ListAssignDLL(Config,DLL);
  1745.          RunBrowse(Config,Tit);
  1746.       end;
  1747.    end;
  1748.    DLLDestroy;
  1749.    DLLActivatePrevList;
  1750. end; { RunBrowseFile }
  1751.  
  1752.                {*********************************************}
  1753.                {**      W R A P P I N G    L I S T S       **}
  1754.                {*********************************************}
  1755.  
  1756. procedure ListSetTagging(var ListDetails: ListCfg;On:boolean);
  1757. {}
  1758. begin
  1759.    ListDetails.AllowTagging := On;
  1760. end; { ListSetTagging }
  1761.  
  1762. procedure ListSetTwoColors(var ListDetails: ListCfg;On:boolean);
  1763. {}
  1764. begin
  1765.    ListDetails.AllowTwoColors := On;
  1766. end; { ListSetTwoColors }
  1767.  
  1768. procedure ListSetTagColor(var ListDetails: ListCfg; On:boolean);
  1769. {}
  1770. begin
  1771.    ListDetails.ChangeColorsWithTags := On;
  1772. end; { ListSetColorWithTag }
  1773.  
  1774. procedure ListSetColWidth(var ListDetails: ListCfg; Width:byte);
  1775. {}
  1776. begin
  1777.    ListDetails.ColWidth := Width;
  1778.    CalcColRow(Listdetails);
  1779. end; { ListSetColWidth }
  1780.  
  1781. procedure ListAssignHindHook(var ListDetails: ListCfg; Proc:ListHindHook);
  1782. {}
  1783. begin
  1784.    ListDetails.HindHook := Proc;
  1785. end; { ListAssignHindHook }
  1786.  
  1787. procedure ListAssignCharHook(var ListDetails: ListCfg; Proc:KeyPressedHook);
  1788. {}
  1789. begin
  1790.    ListDetails.CharHook := Proc;
  1791. end; { ListAssignCharHook }
  1792.  
  1793. procedure ListAssignSelectHook(var ListDetails: ListCfg; Proc:ListSelectHook);
  1794. {}
  1795. begin
  1796.    ListDetails.SelectHook := Proc;
  1797. end; { ListAssignSelectHook }
  1798.  
  1799. procedure ListAssignColorHook(var ListDetails: ListCfg; Proc:ListColorHook);
  1800. {}
  1801. begin
  1802.    ListDetails.ColorHook := Proc;
  1803. end; { ListColorSelectHook }
  1804.  
  1805. procedure ListRemoveColorHook(var ListDetails: ListCfg);
  1806. {}
  1807. begin
  1808.    ListDetails.ColorHook := NoListColorHook;
  1809. end; { ListRemoveColorHook }
  1810.  
  1811. procedure ListRemoveCharHook(var ListDetails: ListCfg);
  1812. {}
  1813. begin
  1814.    ListDetails.CharHook := NoListCharHook;
  1815. end; { ListRemoveCharHook }
  1816.  
  1817. procedure ListRemoveHindHook(var ListDetails: ListCfg);
  1818. {}
  1819. begin
  1820.    ListDetails.HindHook := NoListHindHook;
  1821. end; { ListRemoveHindHook }
  1822.  
  1823. procedure ListRemoveSelectHook(var ListDetails: ListCfg);
  1824. {}
  1825. begin
  1826.    ListDetails.SelectHook := ListDefaultSelectHook;
  1827. end; { ListRemoveSelectHook }
  1828.  
  1829. procedure ListAssignArray(var ListDetails: ListCfg; var ListSource; StrLen:Byte;ArrayElements:byte);
  1830. {}
  1831. begin
  1832.    with ListDetails do
  1833.    begin
  1834.       DataSource := @ListSource;
  1835.       DataType := SourceArray;
  1836.       TotalNodes := ArrayElements;
  1837.       ActiveNode := 1;
  1838.       TopNode := 1;
  1839.       StrLength := Strlen;
  1840.       GetStr := ArrayGetStrFunc;
  1841.    end;
  1842. end; {ListAssignArray}
  1843.  
  1844. procedure ListAssignSLL(var ListDetails: ListCfg; var TheList:SingleLL);
  1845. {}
  1846. begin
  1847.    with ListDetails do
  1848.    begin
  1849.       DataSource := @TheList;
  1850.       DataType := SourceSLL;
  1851.       TotalNodes := TheList.TotalNodes;
  1852.       ActiveNode := 1;
  1853.       TopNode := 1;
  1854.       GetStr := SLLGetStrFunc;
  1855.       GetBit := SLLGetBitFunc;
  1856.       SetBit := SLLSetBitFunc;
  1857.    end;
  1858. end; {ListAssignSLL}
  1859.  
  1860. procedure ListAssignDLL(var ListDetails: ListCfg; var TheList:DoubleLL);
  1861. {}
  1862. begin
  1863.    with ListDetails do
  1864.    begin
  1865.       DataSource := @TheList;
  1866.       DataType := SourceDLL;
  1867.       TotalNodes := TheList.TotalNodes;
  1868.       ActiveNode := 1;
  1869.       TopNode := 1;
  1870.       GetStr := DLLGetStrFunc;
  1871.       GetBit := DLLGetBitFunc;
  1872.       SetBit := DLLSetBitFunc;
  1873.    end;
  1874. end; {ListAssignDLL}
  1875.  
  1876. procedure ListAssignCustom(var ListDetails: ListCfg; Total:longint; Proc:ListGetStrFunc);
  1877. {}
  1878. begin
  1879.    with ListDetails do
  1880.    begin
  1881.       GetStr := Proc;
  1882.       DataType := SourceCustom;
  1883.       TotalNodes := Total;
  1884.       AllowTagging := false;
  1885.       ActiveNode := 1;
  1886.       TopNode := 1;
  1887.    end;
  1888. end; {ListAssignCustom}
  1889.  
  1890. procedure RecalcListDimensions(var ListDetails: ListCfg);
  1891. {}
  1892. var
  1893.   ListWidth: byte;
  1894. begin
  1895.    with ListDetails do
  1896.    begin
  1897.       if ColWidth <> 0 then
  1898.          RealColWidth := ColWidth;
  1899.       ListWidth := X2-X1;
  1900.       if RealColWidth > ListWidth then
  1901.          RealColWidth := ListWidth;
  1902.       ColCount := ListWidth div RealColWidth;
  1903.       LastColWidth := ListWidth - ColCount * RealColWidth;
  1904.       if LastColWidth = 0 then
  1905.          LastColWidth := RealColWidth
  1906.       else
  1907.          inc(ColCount);
  1908.       RowCount := succ(Y2-Y1);
  1909.    end;
  1910. end; { RecalcListDimensions }
  1911.  
  1912. procedure WrapListWriteItem(var ListDetails: ListCfg; ItemNum:longint; Status:gStatus);
  1913. {}
  1914. var
  1915.   X,Y,
  1916.   A:byte;
  1917.   Str:StrScreen;
  1918.   AvailWidth,
  1919.   TextWidth: shortint;
  1920. begin
  1921.    with ListDetails do
  1922.    begin
  1923.       if TotalNodes = 0 then
  1924.          exit;
  1925.       if (ColCount > 1)
  1926.       and (ItemNum - pred(TopNode) > RowCount * pred(ColCount))
  1927.       and (LastColWidth <> RealColWidth) then
  1928.          AvailWidth := LastColWidth
  1929.       else
  1930.          AvailWidth := RealColWidth;
  1931.       if ItemNum <= TotalNodes then
  1932.       begin
  1933.          with ListVars do
  1934.             TextWidth := AvailWidth
  1935.                          - length(ListLeft)
  1936.                          - length(ListRight)
  1937.                          - ord(AllowTagging) * length(ListTag);
  1938.          if TextWidth > 0 then
  1939.             Str := GetStr(Listdetails.DataSource,ItemNum,1,TextWidth)
  1940.          else
  1941.             Str := '';
  1942.          if AllowTagging then  {add the tag character}
  1943.          begin
  1944.             if GetBit(DataSource,ItemNum,TagBit) then
  1945.                Str := ListVars.ListTag + Str
  1946.             else
  1947.                Str := replicate(length(ListVars.ListTag),' ')+Str;
  1948.          end;
  1949.          if (AllowTwoColors or ChangeColorsWithTags)
  1950.          and GetBit(DataSource,ItemNum,ColBit) then
  1951.             A := Col[ListNorm2]
  1952.          else
  1953.             A := Col[ListNorm1];
  1954.          if ItemNum = ActiveNode then
  1955.          begin
  1956.             Str := ListVars.ListLeft + Str + ListVars.ListRight;
  1957.             (*
  1958.             if (Status in [HiStatus,Activate]) then
  1959.             begin
  1960.             *)
  1961.                if (AllowTwoColors or ChangeColorsWithTags) and GetBit(DataSource,ItemNum,ColBit) then
  1962.                   A := Col[ListHi2]
  1963.                else
  1964.                   A := Col[ListHi1];
  1965.             (*
  1966.             end;
  1967.             *)
  1968.          end
  1969.          else
  1970.             Str := replicate(length(ListVars.ListLeft),' ')+Str+replicate(length(ListVars.ListRight),' ');
  1971.       end
  1972.       else
  1973.       begin
  1974.          A := Col[ListNorm1];
  1975.          Str := replicate(AvailWidth,' ');
  1976.       end;
  1977.       {now we've created the item string we have to figure out where
  1978.        to write it}
  1979.       if ItemNum - pred(TopNode) <= RowCount then
  1980.          X := X1
  1981.       else
  1982.          X := pred(X1) + succ(RealColWidth*((ItemNum - TopNode) div RowCount));
  1983.       if (ItemNum - pred(TopNode)) mod RowCount = 0 then
  1984.          Y := pred(Y1) + RowCount
  1985.       else
  1986.          Y := pred(Y1) + (ItemNum - pred(TopNode)) mod RowCount;
  1987.       if length(Str) > AvailWidth then
  1988.          Str := copy(Str,1,AvailWidth);
  1989.       ColorHook(ItemNum,ItemNum = ActiveNode,A);
  1990.       WriteAT(X,Y,A,Str);
  1991.       if (Status in [HiStatus,Activate]) and (ItemNum = ActiveNode) then
  1992.       begin
  1993.          GListWriteScrollBar(Listdetails,HiStatus);
  1994.          gotoxy(X,Y);
  1995.       end;
  1996.    end;
  1997. end; { WrapListWriteItem }
  1998.  
  1999. procedure WrapListRefresh(var ListDetails: ListCfg; Status:gStatus);
  2000. {Updates the list area}
  2001. var I : longint;
  2002. begin
  2003.    with ListDetails do
  2004.    begin
  2005.       if (LastColWidth = RealColWidth) or (ColCount = 1) then
  2006.          I := ColCount*RowCount
  2007.       else
  2008.          I := pred(ColCount)*RowCount;
  2009.       if (ActiveNode < TopNode)
  2010.       or (ActiveNode > pred(TopNode) + I)
  2011.       or (ActiveNode > TotalNodes) then
  2012.          ActiveNode := TopNode;
  2013.       for I := TopNode to (pred(TopNode) + (RowCount * ColCount)) do
  2014.           WrapListWriteItem(ListDetails,I,Status);
  2015.    end;
  2016. end; {WrapListRefresh}
  2017.  
  2018.  
  2019.  
  2020. function WrapScrollUp(var ListDetails: ListCfg): boolean;
  2021. {Updates the ActiveNode and TopNode parameters and returns
  2022.  true if TopNode is modified, i.e. if the list needs to be
  2023.  refreshed}
  2024. begin
  2025.    WrapScrollUp := false;
  2026.    with ListDetails do
  2027.    begin
  2028.       if ActiveNode > TopNode then
  2029.          dec(ActiveNode)
  2030.       else if TopNode > 1 then
  2031.       begin
  2032.          dec(TopNode);
  2033.          ActiveNode := TopNode;
  2034.          WrapScrollUp := true;
  2035.       end;
  2036.    end;
  2037. end; {WrapScrollUp}
  2038.  
  2039. function WrapScrollDown(var ListDetails: ListCfg): boolean;
  2040. {Updates the ActiveNode and TopNode parameters and returns
  2041.  true if TopNode is modified, i.e. if the list needs to be
  2042.  refreshed}
  2043. var LastPick : longint;
  2044. begin
  2045.    WrapScrollDown := false;
  2046.    with ListDetails do
  2047.    begin
  2048.       if ActiveNode < TotalNodes then
  2049.       begin
  2050.          if (ColCount = 1) or (LastColWidth = RealColWidth) then
  2051.             LastPick := ColCount * RowCount
  2052.          else
  2053.             LastPick := pred(ColCount) * RowCount;
  2054.          if ActiveNode < pred(TopNode) + LastPick then
  2055.             inc(ActiveNode)
  2056.          else
  2057.          begin
  2058.             inc(TopNode);
  2059.             inc(ActiveNode);
  2060.             WrapScrollDown := true;
  2061.          end;
  2062.       end;
  2063.    end;
  2064. end; {WrapScrollDown}
  2065.  
  2066. function WrapScrollLeft(var ListDetails: ListCfg): boolean;
  2067. {Updates the ActiveNode and TopNode parameters and returns
  2068.  true if TopNode is modified, i.e. if the list needs to be
  2069.  refreshed}
  2070. begin
  2071.    with ListDetails do
  2072.    begin
  2073.       if (ColCount = 1) or ((ColCount = 2) and (LastColWidth <> RealColWidth)) then
  2074.          WrapScrollLeft := WrapScrollUp(ListDetails)
  2075.       else
  2076.       begin
  2077.          if ActiveNode > pred(TopNode) + RowCount then {not in first Col}
  2078.          begin
  2079.             WrapScrollLeft := false;
  2080.             dec(ActiveNode,RowCount);
  2081.          end
  2082.          else if TopNode > RowCount then
  2083.          begin
  2084.             WrapScrollLeft := true;
  2085.             dec(ActiveNode,RowCount);
  2086.             dec(TopNode,RowCount);
  2087.          end
  2088.          else
  2089.          begin
  2090.             WrapScrollLeft := true;
  2091.             ActiveNode := 1;
  2092.             TopNode := 1;
  2093.          end;
  2094.       end;
  2095.    end;
  2096. end; {WrapScrollLeft}
  2097.  
  2098. function WrapScrollRight(var ListDetails: ListCfg): boolean;
  2099. {Updates the ActiveNode and TopNode parameters and returns
  2100.  true if TopNode is modified, i.e. if the list needs to be
  2101.  refreshed}
  2102. begin
  2103.    with ListDetails do
  2104.    begin
  2105.       if (ColCount = 1) or ((ColCount = 2) and (LastColWidth <> RealColWidth)) then
  2106.          WrapScrollRight := WrapScrollDown(ListDetails)
  2107.       else
  2108.       begin
  2109.          inc(ActiveNode,RowCount);
  2110.          if ActiveNode > TotalNodes then
  2111.             ActiveNode := TotalNodes;
  2112.          if ActiveNode <= pred(TopNode) + ( (ColCount-ord(LastColWidth <> RealColWidth)) * RowCount) then
  2113.             WrapScrollRight := false
  2114.          else
  2115.          begin
  2116.             WrapScrollRight := true;
  2117.             inc(TopNode,RowCount);
  2118.             if TopNode > TotalNodes then
  2119.                TopNode := TotalNodes;
  2120.          end;
  2121.       end;
  2122.    end;
  2123. end; {WrapScrollRight}
  2124.  
  2125. function WrapScrollPgDn(var ListDetails: ListCfg): boolean;
  2126. {Updates the ActiveNode and TopNode parameters and returns
  2127.  true if TopNode is modified, i.e. if the list needs to be
  2128.  refreshed}
  2129. begin
  2130.    with ListDetails do
  2131.    begin
  2132.       if pred(TopNode) + RowCount < TotalNodes then
  2133.       begin
  2134.          inc(TopNode,RowCount);
  2135.          ActiveNode := TopNode;
  2136.          WrapScrollPgDn := true;
  2137.       end
  2138.       else
  2139.          WrapScrollPgDn := false;
  2140.    end;
  2141. end; {WrapScrollPgDn}
  2142.  
  2143. function WrapScrollPgUp(var ListDetails: ListCfg): boolean;
  2144. {Updates the ActiveNode and TopNode parameters and returns
  2145.  true if TopNode is modified, i.e. if the list needs to be
  2146.  refreshed}
  2147. begin
  2148.    with ListDetails do
  2149.    begin
  2150.       if ActiveNode > 1 then
  2151.       begin
  2152.          if TopNode > 1 then
  2153.          begin
  2154.             WrapScrollPgUp := true;
  2155.             dec(TopNode,RowCount);
  2156.             dec(ActiveNode,RowCount);
  2157.             if TopNode < 1 then
  2158.                TopNode := 1;
  2159.             if ActiveNode < TopNode then
  2160.                ActiveNode := TopNode;
  2161.          end
  2162.          else
  2163.          begin
  2164.             WrapScrollPgUp := false;
  2165.             ActiveNode := 1;
  2166.          end;
  2167.       end;
  2168.    end;
  2169. end; {WrapScrollPgUp}
  2170.  
  2171. function WrapScrollHome(var ListDetails: ListCfg): boolean;
  2172. {Updates the ActiveNode and TopNode parameters and returns
  2173.  true if TopNode is modified, i.e. if the list needs to be
  2174.  refreshed}
  2175. begin
  2176.    with ListDetails do
  2177.    begin
  2178.       WrapScrollHome := (TopNode > 1);
  2179.       TopNode := 1;
  2180.       ActiveNode := 1;
  2181.    end;
  2182. end; {WrapScrollHome}
  2183.  
  2184. function WrapScrollEnd(var ListDetails: ListCfg): boolean;
  2185. {Updates the ActiveNode and TopNode parameters and returns
  2186.  true if TopNode is modified, i.e. if the list needs to be
  2187.  refreshed}
  2188. begin
  2189.    with ListDetails do
  2190.    begin
  2191.       if TopNode + pred((ColCount -ord(not (LastColWidth = RealColWidth))) * RowCount)
  2192.          >= TotalNodes then {last node on display}
  2193.          WrapScrollEnd := false
  2194.       else
  2195.       begin
  2196.          WrapScrollEnd := true;
  2197.          TopNode := TotalNodes;
  2198.       end;
  2199.       ActiveNode := TotalNodes;
  2200.    end;
  2201. end; {WrapScrollEnd}
  2202.  
  2203. function WrapScrollChar(var ListDetails: ListCfg;Ch:char): boolean;
  2204. {Updates the ActiveNode and TopNode parameters and returns
  2205.  true if TopNode is modified, i.e. if the list needs to be
  2206.  refreshed}
  2207. var
  2208.    LastPick,
  2209.    L: longint;
  2210.    Str:string[1];
  2211.    Found:boolean;
  2212. begin
  2213.    WrapScrollChar := false;
  2214.    with ListDetails do
  2215.    begin
  2216.       {first search from top of list looking for match}
  2217.       L := 0;
  2218.       Found := false;
  2219.       while not found and (L <= TotalNodes) do
  2220.       begin
  2221.          inc(L);
  2222.          Str := GetStr(Listdetails.DataSource,L,1,1);
  2223.          Found := Str[1] = Ch;
  2224.       end;
  2225.       if Found then
  2226.       begin
  2227.          ActiveNode := L;
  2228.          if (ColCount = 1) or (LastColWidth = RealColWidth) then
  2229.             LastPick := ColCount * RowCount
  2230.          else
  2231.             LastPick := pred(ColCount) * RowCount;
  2232.          if (ActiveNode < TopNode)
  2233.          or (ActiveNode > pred(TopNode) + LastPick) then
  2234.          begin
  2235.             TopNode := ActiveNode;
  2236.             WrapScrollChar := true;
  2237.          end;
  2238.       end;
  2239.    end;
  2240. end; {WrapScrollChar}
  2241.  
  2242.                           {*********************}
  2243.                           {**  Tagging Procs  **}
  2244.                           {*********************}
  2245.  
  2246. procedure ToggleTagState(var ListDetails: ListCfg);
  2247. {}
  2248. var On: boolean;
  2249. begin
  2250.    with ListDetails do
  2251.    if AllowTagging then
  2252.    begin
  2253.       On := not GetBit(DataSource,ActiveNode,TagBit);
  2254.       SetBit(DataSource,ActiveNode,TagBit,On);
  2255.       if ChangeColorsWithTags then
  2256.          SetBit(DataSource,ActiveNode,ColBit,On);
  2257.       WrapListWriteItem(Listdetails,ActiveNode,HiStatus);
  2258.    end;
  2259. end; { ToggleTagState }
  2260.  
  2261. procedure SetTag(var ListDetails: ListCfg; On: boolean);
  2262. {}
  2263. var State: boolean;
  2264. begin
  2265.    with ListDetails do
  2266.    if AllowTagging then
  2267.    begin
  2268.       State := GetBit(DataSource,ActiveNode,TagBit);
  2269.       if State <> On then
  2270.       begin
  2271.          SetBit(DataSource,ActiveNode,TagBit,On);
  2272.          if ChangeColorsWithTags then
  2273.             SetBit(DataSource,ActiveNode,ColBit,On);
  2274.          WrapListWriteItem(Listdetails,ActiveNode,HiStatus);
  2275.       end;
  2276.    end;
  2277. end; { SetTag }
  2278.  
  2279. procedure SetTagAll(var ListDetails: ListCfg; On: boolean);
  2280. {}
  2281. var I : longint;
  2282. begin
  2283.    with ListDetails do
  2284.    if AllowTagging then
  2285.    begin
  2286.       for I := 1 to TotalNodes do
  2287.       begin
  2288.          SetBit(DataSource,I,TagBit,On);
  2289.          if ChangeColorsWithTags then
  2290.             SetBit(DataSource,I,ColBit,On);
  2291.       end;
  2292.       WrapListRefresh(ListDetails,HiStatus)
  2293.    end;
  2294. end; { SetTagAll }
  2295.  
  2296. procedure WrapMoveIt(var ListDetails: ListCfg; Direction: byte);
  2297. {}
  2298. var
  2299.   Repaint: boolean;
  2300.   OldAct: longint;
  2301. begin
  2302.    with ListDetails do
  2303.    begin
  2304.       OldAct := ActiveNode;
  2305.       if ((Direction in [1,3,5]) and (ActiveNode = 1))
  2306.       or ((Direction in [2,4,6]) and (ActiveNode = TotalNodes)) then
  2307.          exit;
  2308.       case Direction of
  2309.         1: Repaint := WrapScrollUp(ListDetails);
  2310.         2: Repaint := WrapScrollDown(ListDetails);
  2311.         3: Repaint := WrapScrollPgUp(ListDetails);
  2312.         4: Repaint := WrapScrollPgDn(ListDetails);
  2313.         5: Repaint := WrapScrollHome(ListDetails);
  2314.         6: Repaint := WrapScrollEnd(ListDetails);
  2315.         7: Repaint := WrapScrollLeft(ListDetails);
  2316.         8: Repaint := WrapScrollRight(ListDetails);
  2317.       end;
  2318.       if Repaint then
  2319.          WrapListRefresh(ListDetails,HiStatus)
  2320.       else if OldAct <> ActiveNode then
  2321.       begin
  2322.          WrapListWriteItem(ListDetails,OldAct,HiStatus);
  2323.          WrapListWriteItem(ListDetails,ActiveNode,HiStatus);
  2324.       end;
  2325.    end;
  2326. end; { WrapMoveIt }
  2327.  
  2328. procedure WrapMouseVScroll(var ListDetails: ListCfg);
  2329. {}
  2330. var
  2331.   L,M,R: boolean;
  2332.   X,Y,ElevatorY:byte;
  2333.   WaitTime: integer;
  2334.  
  2335.   procedure ScrollUpOne;
  2336.   {}
  2337.   begin
  2338.      with ListDetails do
  2339.      repeat
  2340.         MouseStatusWin(L,M,R,X,Y);
  2341.         if (X = X2) and (Y = Y1) and L then
  2342.            WrapMoveIt(Listdetails,1);
  2343.         DelayIt(L,InWindow,WaitTime);
  2344.      until not L;
  2345.   end; { ScrollUpOne }
  2346.  
  2347.   procedure ScrollDownOne;
  2348.   {}
  2349.   begin
  2350.      with ListDetails do
  2351.      repeat
  2352.         MouseStatusWin(L,M,R,X,Y);
  2353.         if (X = X2) and (Y = Y2) and L then
  2354.            WrapMoveIt(ListDetails,2);
  2355.         DelayIt(L,InWindow,WaitTime);
  2356.      until not L;
  2357.   end; { ScrollDownOne }
  2358.  
  2359.   procedure ScrollUpward;
  2360.   {}
  2361.   begin
  2362.      with ListDetails do
  2363.      repeat
  2364.         MouseStatusWin(L,M,R,X,Y);
  2365.         if ActiveNode <> 1 then
  2366.         begin
  2367.            if (X = X2) and (Y >= Y1) and (Y <= ElevatorY) and L then
  2368.               WrapMoveIt(ListDetails,3);   {PgUp effect}
  2369.            DelayIt(L,InWindow,WaitTime);
  2370.         end;
  2371.      until not L;
  2372.   end; { ScrollUpward }
  2373.  
  2374.   procedure ScrollDownward;
  2375.   {}
  2376.   begin
  2377.      with ListDetails do
  2378.      repeat
  2379.         MouseStatusWin(L,M,R,X,Y);
  2380.         if ActiveNode <> TotalNodes then
  2381.         begin
  2382.            if (X = X2) and (Y <= Y2) and (Y >= ElevatorY) and L then
  2383.               WrapMoveIt(ListDetails,4);   {PgDn effect}
  2384.            DelayIt(L,InWindow,WaitTime);
  2385.         end;
  2386.      until not L;
  2387.   end; { ScrollDownward }
  2388.  
  2389.   procedure ScrollDragElevator;
  2390.   {}
  2391.   var
  2392.     OldY:byte;
  2393.     NewActive:longint;
  2394.   begin
  2395.      OldY := Y;
  2396.      with ListDetails do
  2397.      repeat
  2398.         MouseStatusWin(L,M,R,X,Y);
  2399.         if (X = X2) and (Y < Y2) and (Y > Y1) and (Y <> OldY) and L then
  2400.         begin
  2401.            OldY := Y;
  2402.            if Y = succ(Y1) then
  2403.               NewActive := 1
  2404.            else if Y = pred(Y2) then
  2405.               NewActive := TotalNodes
  2406.            else
  2407.               NewActive := TotalNodes * (Y - Y1) div (Y2-Y1);
  2408.            if NewActive <> ActiveNode then
  2409.            begin
  2410.               ActiveNode := NewActive;
  2411.               TopNode := NewActive;
  2412.               WrapListRefresh(ListDetails,HiStatus);
  2413.            end;
  2414.            if WindowHasFocus then
  2415.               WinDrawTop;
  2416.         end;
  2417.      until not L;
  2418.   end; { ScrollElevator }
  2419.  
  2420. begin
  2421.    with ListDetails do
  2422.    begin
  2423.       InWindow := WindowHasFocus;
  2424.       WaitTime := KeyVars.InitScrollDelay;
  2425.       repeat
  2426.          MouseStatusWin(L,M,R,X,Y);
  2427.          if L and (X = X2) then
  2428.          begin
  2429.             if Y = Y1 then
  2430.                ScrollUpOne
  2431.             else if Y = Y2 then
  2432.                ScrollDownOne
  2433.             else    {mouse pressed along scroll bar body}
  2434.             begin
  2435.                ElevatorY := GetVScrollBarElevator(Y1,Y2,ActiveNode,TotalNodes);
  2436.                if ((Y = succ(Y1)) and (Y=ElevatorY) and (ActiveNode > 1))
  2437.                or (Y > Y1) and (Y < ElevatorY) then
  2438.                   ScrollUpward
  2439.                else if ((Y = pred(Y2)) and (Y=ElevatorY)
  2440.                         and
  2441.                         (ActiveNode < TotalNodes)
  2442.                        )
  2443.                        or ((Y < Y2) and (Y > ElevatorY))  then
  2444.                   ScrollDownward
  2445.                else {user is dragging elevator}
  2446.                   ScrollDragElevator;
  2447.              end;
  2448.          end;
  2449.       until not L;
  2450.       MouseRelease;
  2451.    end;
  2452. end; { WrapMouseVScroll }
  2453.  
  2454. function WrapTargetPick(var ListDetails: ListCfg;X,Y:byte): longint;
  2455. {return the pick number of the pick pointed to by
  2456.  the coordinates X,Y. If no pick is at those coordinates, a
  2457.  0 is returned}
  2458. begin
  2459.    with ListDetails do
  2460.    begin
  2461.       if  (X >= X1)
  2462.       and (X < X2)   {last column is for scroll bar}
  2463.       and (Y >= Y1)
  2464.       and (Y <= Y2)
  2465.       then
  2466.       begin
  2467.          X := succ(X - X1);
  2468.          Y := succ(Y - Y1);
  2469.          if X mod RealColWidth = 0 then
  2470.             X := X div RealColWidth
  2471.          else
  2472.             X := succ(X div RealColWidth);
  2473.          if (X < ColCount)
  2474.          or ((X = ColCount) and (LastColWidth = RealColWidth)) then
  2475.          begin
  2476.              if TopNode + pred(pred(X)*RowCount + Y) <= TotalNodes then
  2477.              begin
  2478.                 WrapTargetPick := pred(TopNode) + pred(X)*RowCount + Y;
  2479.                 exit;
  2480.              end;
  2481.          end;
  2482.       end;
  2483.       WrapTargetPick := 0;
  2484.    end;
  2485. end; {WrapTargetPick}
  2486.  
  2487. procedure WrapMouseSelect(var ListDetails: ListCfg);
  2488. {Called when mouse pressed on field and held down}
  2489. var
  2490.   L,M,R: boolean;
  2491.   X,Y:byte;
  2492.   OldAct,
  2493.   NewAct: longint;
  2494.  
  2495.    function OnActiveNode: boolean;
  2496.    {}
  2497.    begin
  2498.       MouseStatusWin(L,M,R,X,Y);
  2499.       with ListDetails do
  2500.       OnActiveNode := (ActiveNode = WrapTargetPick(Listdetails,X,Y));
  2501.    end; { OnActiveNode }
  2502.  
  2503.    function CheckforTagChange:boolean;
  2504.    {}
  2505.    begin
  2506.       CheckForTagChange := false;
  2507.       with Listdetails do
  2508.       if AllowTagging then
  2509.       begin
  2510.          if OnActiveNode and L then
  2511.          begin
  2512.             ToggleTagState(Listdetails);
  2513.             if WindowHasFocus then
  2514.                WinDrawTop;
  2515.             MouseRelease;
  2516.             if OnActiveNode then
  2517.                CheckForTagChange := true
  2518.             else
  2519.                ToggleTagState(Listdetails);
  2520.          end;
  2521.       end;
  2522.    end; { CheckforTagChange }
  2523.  
  2524. begin
  2525.    if not CheckForTagChange then
  2526.    with ListDetails do
  2527.    repeat
  2528.       MouseStatusWin(L,M,R,X,Y);
  2529.       if L then
  2530.       begin
  2531.          OldAct := ActiveNode;
  2532.          NewAct := WrapTargetPick(Listdetails,X,Y);
  2533.          if (NewAct <> 0) then
  2534.          begin
  2535.             if (NewAct <> OldAct) then
  2536.             begin
  2537.                ActiveNode := NewAct;
  2538.                WrapListWriteItem(ListDetails,OldAct,HiStatus);
  2539.                WrapListWriteItem(ListDetails,ActiveNode,HiStatus);
  2540.                if WindowHasFocus then
  2541.                   WinDrawTop;
  2542.             end;
  2543.             (*
  2544.             CursorOn;
  2545.             *)
  2546.          end
  2547.          else
  2548.          (*
  2549.             CursorOff;
  2550.          *);
  2551.       end;
  2552.    until not L;
  2553.    MouseRelease;
  2554. end; {WrapMouseSelect}
  2555.  
  2556. procedure WrapWindowStretch(var Listdetails: ListCfg);
  2557. {Called when user stretches the window}
  2558. var
  2559.    WP: WStructurePtr;
  2560. begin
  2561.    {First set the listdetails to reflect the revised window dimensions}
  2562.    WP := WinPtr(0); {top window}
  2563.    with Listdetails do
  2564.    begin
  2565.       WX1 := WP^.X;
  2566.       WY1 := WP^.Y;
  2567.       WX2 := WX1 + pred(WP^.Width);
  2568.       WY2 := WY1 + pred(WP^.Depth);
  2569.    end;
  2570.    SetInnerDimensions(Listdetails);
  2571.    CalcColRow(Listdetails);
  2572.    ReCalcListDimensions(ListDetails);
  2573.    RefreshHeadFoot(Listdetails);
  2574.    WrapListRefresh(ListDetails,HiStatus);
  2575.    WinDrawAll;
  2576. end; {WrapWindowStretch}
  2577.  
  2578. procedure WrapListProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  2579. {}
  2580. var
  2581.    Ch: char;
  2582.    OldAct:longint;
  2583. begin
  2584.    with ListDetails do
  2585.    begin
  2586.       CharHook(K,X,Y); {call user hook}
  2587.       if MakeLocal then
  2588.          if IsWinKey(K,X,Y) then
  2589.             WinProcessKey(K,X,Y);
  2590.       K := CapitalWord(K);
  2591.       if (K = 500) or (K = 540) then
  2592.       begin
  2593.          if MakeLocal then {convert to local coords}
  2594.          begin
  2595.             X := WinLocalX(0,X);
  2596.             Y := WinLocalY(0,Y);
  2597.          end;
  2598.          if (K = 500) then
  2599.          begin
  2600.             if (X = X2) and (TotalNodes > succ(Y2-Y1)) then
  2601.                WrapMouseVScroll(Listdetails)
  2602.             else
  2603.                WrapMouseSelect(Listdetails);
  2604.          end
  2605.          else if WrapTargetPick(Listdetails,X,Y) <> 0 then
  2606.             K := 540; {double click}
  2607.       end
  2608.       else if K = ListVars.ToggleKey then
  2609.            ToggleTagState(Listdetails)
  2610.       else if K = ListVars.TagKey then
  2611.            SetTag(Listdetails,true)
  2612.       else if K = ListVars.UnTagKey then
  2613.            SetTag(Listdetails,false)
  2614.       else if K = ListVars.TagAllKey then
  2615.            SetTagAll(Listdetails,true)
  2616.       else if K = ListVars.UnTagAllKey then
  2617.            SetTagAll(Listdetails,false)
  2618.       else
  2619.       case K of
  2620.          328: WrapMoveIt(ListDetails,1);
  2621.          336: WrapMoveIt(ListDetails,2);
  2622.          329: WrapMoveIt(ListDetails,3);
  2623.          337: WrapMoveIt(ListDetails,4);
  2624.          327: WrapMoveIt(ListDetails,5);
  2625.          335: WrapMoveIt(ListDetails,6);
  2626.          331: WrapMoveIt(ListDetails,7);
  2627.          333: WrapMoveIt(ListDetails,8);
  2628.          602: if WindowHasFocus then
  2629.                  WrapWindowStretch(Listdetails);
  2630.          else if (K >= 55) and (K <= 255) then
  2631.          begin
  2632.             Ch := chr(CapitalWord(K));
  2633.             OldAct := ActiveNode;
  2634.             if WrapScrollChar(Listdetails,Ch) then
  2635.                WrapListRefresh(ListDetails,HiStatus)
  2636.             else if OldAct <> ActiveNode then
  2637.             begin
  2638.                WrapListWriteItem(ListDetails,OldAct,HiStatus);
  2639.                WrapListWriteItem(ListDetails,ActiveNode,HiStatus);
  2640.             end;
  2641.          end;
  2642.       end; {case}
  2643.       LastKey := K;
  2644.       HindHook(@ListDetails);
  2645.    end;
  2646. end; { WrapListProcessKey }
  2647.  
  2648. function DisplayListEngine(var ListDetails: ListCfg;Tit:StrScreen): byte;
  2649. {INTERNAL}
  2650. var
  2651.   Handle: integer;
  2652.  
  2653.    procedure SetWindow;
  2654.    {}
  2655.    begin
  2656.       with ListVars do
  2657.       begin
  2658.          with ListDetails do
  2659.             Handle := WinCreate(WX1,WY1,WX2,WY2,WStyle);
  2660.          WinSetType(Handle,WrapWinType);
  2661.          WinSetTitle(Handle,Tit);
  2662.          WinSetShowNum(Handle,false);
  2663.          WinSetColor(Handle,WinBorder,Listdetails.Col[ListBorder1]);
  2664.          WinSetColor(Handle,WinBorder3DOut,Listdetails.Col[ListBorder1]);
  2665.          WinSetColor(Handle,WinBorder3dIn,Listdetails.Col[ListBorder2]);
  2666.          WinSetColor(Handle,WinBorderOff,Listdetails.Col[ListBorderOff]);
  2667.          WinSetColor(Handle,WinIcons,Listdetails.Col[ListIcons]);
  2668.          WinSetColor(Handle,WinBody,Listdetails.Col[ListNorm1]);
  2669.          WinSetColor(Handle,WinTitle,Listdetails.Col[ListTitle]);
  2670.          if ListDetails.ColWidth <> 0 then
  2671.             WinSetMinSize(Handle,ListDetails.ColWidth+2+2*ord(WinStyle in [7,8]),WinVars.MinDepth);
  2672.          WinPaint(Handle);
  2673.       end;
  2674.    end; {SetWindow}
  2675.  
  2676. begin
  2677.    with ListDetails do
  2678.    begin
  2679.       if WX1 = 0 then  {user hasn't set the window}
  2680.       begin
  2681.          WX1 := ListVars.WX1;
  2682.          WY1 := ListVars.WY1;
  2683.          WX2 := ListVars.WX2;
  2684.          WY2 := ListVars.WY2;
  2685.       end;
  2686.       if AllowTagging then {Jubelt}
  2687.          inc(WX2);
  2688.    end;
  2689.    SetInnerDimensions(Listdetails);
  2690.    ListDetails.InWindow := true;
  2691.    CalcColRow(Listdetails);
  2692.    ReCalcListDimensions(ListDetails);
  2693.    SetWindow;
  2694.    WinDisplay(Handle);
  2695.    RefreshHeadFoot(Listdetails);
  2696.    WrapListRefresh(ListDetails,HiStatus);
  2697.    ListDetails.HindHook(@ListDetails); {call it once after window is created}
  2698.    DisplayListEngine := Handle;
  2699. end; {DisplayListEngine}
  2700.  
  2701. procedure ProcessListInput(var ListDetails: ListCfg;OnDeskTop:boolean);
  2702. {}
  2703. begin
  2704.    with Listdetails do
  2705.    with KeyVars do
  2706.    begin
  2707.       WrapListProcessKey(ListDetails,LastKey,LastX,LastY,true);
  2708.       if not OnDeskTop
  2709.       and (
  2710.               (LastKey = 600)
  2711.            or (LastKey = 27)
  2712.            or ((LastKey = 540) and (LastX <> 0))
  2713.            or (LastKey = 13)
  2714.           ) then
  2715.       begin
  2716.           LastAction := SelectHook(@ListDetails);
  2717.           if LastAction = Refresh then
  2718.           begin
  2719.              case DataType of
  2720.                 SourceStrLL: TotalNodes := StringLL(dataSource^).TotalNodes;
  2721.                 SourceSLL: TotalNodes := LinkVars.ActiveSLL^.TotalNodes;
  2722.                 SourceDLL: TotalNodes := LinkVars.ActiveDLL^.TotalNodes;
  2723.              end;
  2724.              ActiveNode := 1;
  2725.              TopNode := 1;
  2726.              WrapListRefresh(ListDetails,HiStatus)
  2727.           end;
  2728.       end
  2729.       else
  2730.       begin
  2731.          if LastKey = 600 then
  2732.             LastAction := Escaped
  2733.          else
  2734.             LastAction := none;
  2735.       end;
  2736.    end;
  2737. end; { ProcessListInput }
  2738.  
  2739. procedure RunList(var ListDetails: ListCfg;Tit:StrScreen);
  2740. {}
  2741. var
  2742.    Handle: integer;
  2743. begin
  2744.    Handle := DisplayListEngine(Listdetails,Tit);
  2745.    WinDrawAll;
  2746.    with Listdetails do
  2747.    with KeyVars do
  2748.    repeat
  2749.       GetInput;
  2750.       ProcessListInput(Listdetails,false);
  2751.       WinDrawAll;
  2752.    until LastAction in [Stop1..Escaped];
  2753.    ListVars.LastActiveItem := ListDetails.ActiveNode;
  2754.    WinDispose(Handle);
  2755.    MouseRelease;
  2756. end; {RunList}
  2757.  
  2758.                         {**************************}
  2759.                         {**  Desktop Management  **}
  2760.                         {**************************}
  2761.  
  2762. {$IFOPT F-}
  2763.    {$DEFINE FOFF}
  2764.    {$F+}
  2765. {$ENDIF}
  2766. function ListCloseHandler(Handle: integer):boolean;
  2767. {}
  2768. var
  2769.    WinP: WStructurePtr;
  2770. begin
  2771.    WinP := WinPtr(Handle);
  2772.    if ListCfg(Winp^.UserData^).DeskListCloseCallBack(Winp^.UserData,Handle) then
  2773.    begin
  2774.       WinDispose(Handle);
  2775.       ListCloseHandler := true;
  2776.    end
  2777.    else
  2778.       ListCloseHandler := false;
  2779. end; {ListCloseHandler}
  2780.  
  2781. function BrowseFileCloseHandler(Handle: integer):boolean;
  2782. {}
  2783. var
  2784.    WinP: WStructurePtr;
  2785. begin
  2786.    WinP := WinPtr(Handle);
  2787.    with ListCfg(Winp^.UserData^) do
  2788.       DLLSetActiveList(DoubleLL(DataSource^));
  2789.    DLLDestroy;
  2790.    DLLActivatePrevList;
  2791.    freemem(WinP^.UserData,sizeof(DeskBrowseFileInfo));
  2792.    WinDispose(Handle);
  2793.    BrowseFileCloseHandler := true;
  2794. end; {BrowseFileCloseHandler}
  2795.  
  2796. procedure ListProcessKeyOnDesktop;
  2797. {}
  2798. var
  2799.    Handle: integer;
  2800.    WinP: WStructurePtr;
  2801.    LDP : ^ListCfg;
  2802. begin
  2803.    Handle := WinWithFocus;
  2804.    WinP := WinPtr(Handle);
  2805.    LDP := Winp^.UserData;
  2806.    ProcessListInput(LDP^,true);
  2807.    if LDP^.LastAction in [Stop1..Escaped] then
  2808.       if ListCloseHandler(Handle) then
  2809.          {Close aborted};
  2810. end; { ListProcessKeyOnDesktop }
  2811.  
  2812. procedure BrowseProcessKeyOnDesktop;
  2813. {}
  2814. var
  2815.    Handle: integer;
  2816.    WinP: WStructurePtr;
  2817.    LDP : ^ListCfg;
  2818.    K: word;
  2819.    X,Y: byte;
  2820. begin
  2821.    Handle := WinWithFocus;
  2822.    WinP := WinPtr(Handle);
  2823.    LDP := Winp^.UserData;
  2824.    with KeyVars do
  2825.    begin
  2826.       K := LastKey;
  2827.       X := lastX;
  2828.       Y := LastY;
  2829.    end;
  2830.    BrowseProcessKey(LDP^,K,X,Y,true);
  2831.    (*
  2832.    if LDP^.LastAction in [Stop1..Escaped] then
  2833.       ListCloseHandler(Handle);
  2834.    *)
  2835. end; { BrowseProcessKeyOnDesktop }
  2836.  
  2837. procedure BrowseFileProcessKeyOnDesktop;
  2838. {}
  2839. var
  2840.    Handle: integer;
  2841.    WinP: WStructurePtr;
  2842.    LDP : ^ListCfg;
  2843.    K: word;
  2844.    X,Y: byte;
  2845. begin
  2846.    Handle := WinWithFocus;
  2847.    WinP := WinPtr(Handle);
  2848.    LDP := @DeskBrowseFileInfo(Winp^.UserData^).Cfg;
  2849.  
  2850.    with KeyVars do
  2851.    begin
  2852.       K := LastKey;
  2853.       X := lastX;
  2854.       Y := LastY;
  2855.    end;
  2856.    BrowseProcessKey(LDP^,K,X,Y,true);
  2857.    if LDP^.LastAction in [Stop1..Escaped] then
  2858.       if BrowseFileCloseHandler(Handle) then
  2859.          {close aborted};
  2860. end; { BrowseFileProcessKeyOnDesktop }
  2861.  
  2862. procedure ListFocusHandler(Handle: integer);
  2863. {}
  2864. var
  2865.    WinP: WStructurePtr;
  2866. begin
  2867.    WinP := WinPtr(Handle);
  2868.    with ListCfg(WinP^.UserData^) do
  2869.    begin
  2870.       case DataType of
  2871.          SourceSLL: SLLSetActiveList(SingleLL(DataSource^));
  2872.          SourceDLL: DLLSetActiveList(DoubleLL(DataSource^));
  2873.       end;
  2874.    end;
  2875. end; {ListFocusHandler}
  2876.  
  2877. {$IFDEF FOFF}
  2878.    {$F-}
  2879.    {$UNDEF FOFF}
  2880. {$ENDIF}
  2881.  
  2882. function LaunchList(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  2883. {}
  2884. var
  2885.    WinP: WStructurePtr;
  2886.    Handle: byte;
  2887. begin
  2888.    WinFadeTopWin;
  2889.    Listdetails.DeskListCloseCallBack := CloseProc;
  2890.    if WinVars.DesktopFocusStyle <> 0 then
  2891.       Listdetails.WStyle := WinVars.DesktopFocusStyle;
  2892.    Handle := DisplayListEngine(Listdetails,Tit);
  2893.    if Handle = 0 then
  2894.          ListSetError(1004)
  2895.    else
  2896.    begin
  2897.       WinP := WinPtr(Handle);
  2898.       WinP^.ProcessKeyProc := ListProcessKeyOnDeskTop;
  2899.       WinP^.CloseWinProc := ListCloseHandler;
  2900.       WinP^.ChangeFocusProc := ListFocusHandler;
  2901.       WinP^.UserData := @ListDetails;
  2902.    end;
  2903.    WinDrawTop;
  2904.    LaunchList := Handle;
  2905. end; {LaunchList}
  2906.  
  2907. function LaunchBrowse(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  2908. {}
  2909. var
  2910.    WinP: WStructurePtr;
  2911.    Handle: byte;
  2912. begin
  2913.    with ListDetails do
  2914.    begin
  2915.       if WinVars.DesktopFocusStyle <> 0 then
  2916.          WStyle := WinVars.DesktopFocusStyle;
  2917.       if WX1 = 0 then  {user hasn't set the window}
  2918.       begin
  2919.          WX1 := ListVars.WX1;
  2920.          WY1 := ListVars.WY1;
  2921.          WX2 := ListVars.WX2;
  2922.          WY2 := ListVars.WY2;
  2923.       end;
  2924.       Handle := BrowseCreateWin(WX1,WY1,WX2,WY2,WStyle);
  2925.       if Handle = 0 then
  2926.          ListSetError(1004);
  2927.    end;
  2928.    SetInnerDimensions(Listdetails);
  2929.    ListDetails.InWindow := true;
  2930.    WinFadeTopWin;
  2931.    DisplayBrowseEngine(Handle,Listdetails,Tit);
  2932.    Listdetails.DeskListCloseCallBack := CloseProc;
  2933.    WinP := WinPtr(Handle);
  2934.    WinP^.ProcessKeyProc := BrowseProcessKeyOnDeskTop;
  2935.    WinP^.CloseWinProc := ListCloseHandler;
  2936.    WinP^.ChangeFocusProc := ListFocusHandler;
  2937.    WinP^.UserData := @ListDetails;
  2938.    WinDrawTop;
  2939.    LaunchBrowse := Handle;
  2940. end; {LaunchBrowse}
  2941.  
  2942. function LaunchBrowseFile(Fname:PathStr;Tit:StrScreen): byte;
  2943. {}
  2944. var
  2945.    WinP: WStructurePtr;
  2946.    Handle: byte;
  2947.    BWinStyle: byte;
  2948.    Result: integer;
  2949. begin
  2950.    if WinVars.DesktopFocusStyle <> 0 then
  2951.       BWinStyle := WinVars.DesktopFocusStyle
  2952.    else
  2953.       BWinStyle := ListVars.WinStyle;
  2954.    WinFadeTopWin;
  2955.    with ListVars do
  2956.       Handle := BrowseCreateWin(WX1,WY1,WX2,WY2,BWinStyle);
  2957.    if Handle = 0 then
  2958.       ListSetError(1004)
  2959.    else
  2960.    begin
  2961.       WinP := WinPtr(handle);
  2962.       if GoldMaxAvail < sizeof(DeskBrowseFileInfo) then
  2963.       begin
  2964.          ListSetError(1004);
  2965.          {no point in proceeding}
  2966.          WinDispose(Handle);
  2967.          LaunchBrowseFile := 0;
  2968.          exit;
  2969.       end;
  2970.       getmem(WinP^.UserData,sizeof(DeskBrowseFileInfo));
  2971.       with DeskBrowseFileInfo(WinP^.UserData^) do
  2972.       begin
  2973.          InitDLLStr(DataList);
  2974.          DLLSetActiveList(DataList);
  2975.          Result := DLLLoadFromFile(Fname);
  2976.          if Result <> 0 then
  2977.          begin
  2978.             case Result of
  2979.                1,2: ListSetError(1001);
  2980.                3: ListSetError(1002);
  2981.             end;
  2982.             DLLDestroy;
  2983.             DLLActivatePrevList;
  2984.             WinDispose(Handle);
  2985.             LaunchBrowseFile := 0;
  2986.             exit;
  2987.          end;
  2988.          InitListCFG(Cfg);
  2989.          ListAssignDLL(Cfg,DataList);
  2990.          with CFg do
  2991.          begin
  2992.             WX1 := ListVars.WX1;
  2993.             WY1 := ListVars.WY1;
  2994.             WX2 := ListVars.WX2;
  2995.             WY2 := ListVars.WY2;
  2996.             WStyle := BWinStyle;
  2997.             InWindow := true;
  2998.         end;
  2999.         SetInnerDimensions(Cfg);
  3000.       end; {with}
  3001.    end;
  3002.    WinP := WinPtr(Handle);
  3003.    DisplayBrowseEngine(Handle,DeskBrowseFileInfo(WinP^.UserData^).Cfg,Tit);
  3004.    (*
  3005.    DLLActivatePrevList;
  3006.    *)
  3007.    WinP^.ProcessKeyProc := BrowseFileProcessKeyOnDesktop;
  3008.    WinP^.CloseWinProc := BrowseFileCloseHandler;
  3009.    WinP^.ChangeFocusProc := ListFocusHandler;
  3010.    WinDrawTop;
  3011.    LaunchBrowseFile := Handle;
  3012. end; {LaunchBrowseFile}
  3013.  
  3014. procedure ShowList(var StrArray;StrLength:byte;TotalPicks:integer);
  3015. {Included for backward compatibility with TTT5}
  3016. var ListDetails: ListCfg;
  3017. begin
  3018.    InitListCFG(Listdetails);
  3019.    ListAssignArray(ListDetails,StrArray,StrLength,TotalPicks);
  3020.    ListAssignArray(ListDetails, StrArray, StrLength, TotalPicks);
  3021.    with Listdetails do
  3022.    begin
  3023.       if StrLength < ListVars.WX2 - ListVars.WX1 then
  3024.       begin
  3025.          WX1 := (HardVars.Width - StrLength - 2*ord(WStyle in [7,8])) div 2;
  3026.          WX2 := WX1 + pred(strLength) + 2*ord(WStyle in [7,8]);
  3027.       end
  3028.       else
  3029.       begin
  3030.          WX1 := ListVars.WX1;
  3031.          WX2 := ListVars.WX2;
  3032.       end;
  3033.       if TotalPicks < (ListVars.WY2 - ListVars.WY1 - 1) then
  3034.       begin
  3035.          WY1 := (HardVars.Depth - TotalPicks - 1) div 2;
  3036.          WY2 := WY1 + succ(TotalPicks);
  3037.       end
  3038.       else
  3039.       begin
  3040.          WY1 := ListVars.WY1;
  3041.          WY2 := ListVars.WY2;
  3042.       end;
  3043.    end;
  3044.    RunList(Listdetails,'');
  3045.    if Listdetails.LastAction = Escaped then
  3046.       LPicks := 0
  3047.    else   
  3048.       LPicks := Listdetails.ActiveNode;
  3049. end; {ShowList}
  3050.  
  3051.               {*********************************************}
  3052.               {**  U N I T   I N I T I A L I Z A T I O N  **}
  3053.               {*********************************************}
  3054.  
  3055. procedure ListDefaultSettings;
  3056. {}
  3057. begin
  3058.    with ListVars do
  3059.    begin
  3060.       if ColorScreen then
  3061.       begin
  3062.          ListLeft := ' ';
  3063.          ListRight := ' ';
  3064.       end
  3065.       else
  3066.       begin
  3067.          ListLeft := '';
  3068.          ListRight := '';
  3069.       end;
  3070.       ListTag := '';
  3071.       GridLeft := '';
  3072.       GridRight := '';
  3073.       GridTag := '';
  3074.       ToggleKey := 32;  {spacebar}
  3075.       TagKey :=  84;    {'T'}
  3076.       UnTagKey := 85;   {'U'}
  3077.       TagAllKey := 20;  {Ctrl-T}
  3078.       UnTagAllKey := 21;{Ctrl-U}
  3079.       WinStyle := 7;
  3080.       WX1 := 10;       {default window coordinates}
  3081.       WX2 := 70;
  3082.       WY1 := 2;
  3083.       WY2 := 24;
  3084.       WrapWinType := WStretch;
  3085.       LastActiveItem := 0;
  3086.       EMsgFunc := ListEMsg;
  3087.    end;
  3088. end; { ListDefaultSettings }
  3089.  
  3090.  
  3091. procedure GoldListInit;
  3092. {}
  3093. begin
  3094.    ListDefaultSettings;
  3095. end; {GoldListInit}
  3096.  
  3097. {$IFDEF TTT5}
  3098. procedure Default_Settings;
  3099. {}
  3100. begin
  3101.    {abstract}
  3102. end; { Default_Settings }
  3103.  
  3104. procedure Show_List(var StrArray;StrLength:Byte;TotalPicks:byte);
  3105. {}
  3106. begin
  3107.    ShowList(StrArray,StrLength,TotalPicks);
  3108. end; { Show_List }
  3109.  
  3110. procedure New_Show_List(var StrArray;StrLength:Byte;TotalPicks:byte);
  3111. {}
  3112. begin
  3113.    ShowList(StrArray,StrLength,TotalPicks);
  3114. end; { New_Show_List }
  3115. {$ENDIF}
  3116.  
  3117. begin
  3118.    GoldListInit;
  3119. end.
  3120.